Well, the code
From mathcomp Require Import ssreflect ssrnat ssrbool eqtype.
Unset Strict Implicit.
Unset Printing Implicit Defensive.
Inductive nat_rels m n : bool -> bool -> bool -> Set :=
| CompareNatLt of m < n : nat_rels m n true false false
| CompareNatGt of m > n : nat_rels m n false true false
| CompareNatEq of m == n : nat_rels m n false false true.
Lemma natrelP m n : nat_rels m n (m < n) (m > n) (m == n).
Proof.
case (leqP m n); case (leqP n m).
move => H1 H2; move: (conj H1 H2) => {H1} {H2} /andP.
rewrite -eqn_leq => /eqP /ssrfun.esym /eqP H.
by rewrite H; constructor.
move => H. rewrite leq_eqVlt => /orP.
case.
Error is Error: Case analysis on sort Set is not allowed for inductive definition or.
The last goal before the case is
m, n : nat
H : m < n
============================
m == n \/ m < n -> nat_rels m n true false (m == n)
I've already used this construction (rewrite leq_eqVlt => /orP; case) in very similar situation and it just worked:
Lemma succ_max_distr n m : (maxn n m).+1 = maxn (n.+1) (m.+1).
Proof.
wlog : m n / m < n => H; last first.
rewrite max_l /maxn; last by exact: ltnW.
rewrite leqNgt.
have: m.+1 < n.+2 by apply: ltnW.
by move => ->.
case: (leqP n m); last by apply: H.
rewrite leq_eqVlt => /orP. case.
- What is the difference between two cases?
- and Why "Case analysis on sort Set is not allowed for inductive definition or"?
The difference between the two cases is the sort of the goal (Set vs Prop) when you execute the
casecommand. In the first situation your goal isnat_rels ...and you declared that inductive inSet; in the second situation your goal is an equality that lands inProp.The reason why you can't do a case analysis on
\/when the goal is inSet(the first situation) is because\/has been declared asProp-valued. The main restriction associated to such a declaration is that you cannot use informative content from aPropto build something inSet(or more generallyType), so thatPropis compatible with an erasure-semantic at extraction time.In particular, doing a case analysis on
\/gives away the side of the\/that is valid, and you can't be allowed to use that information for building some data inSet.You have at least two solutions at your disposal:
nat_relsfromSettoPropif that's compatible with what you want to do later on.{m == n} + { m <n }out ofm <= n; here the notation{ _ } + { _ }is theSet-valued disjunction of proposition.