How to prove decidability of a partial order inductive predicate?
Question
Minimal executable example
Require Import Setoid. Ltac inv H := inversion H; clear H; subst. Inductive t : Set := A | B | C. Ltac destruct_ts := repeat match goal with | [ x : t |- _ ] => destruct x end. Inductive le : t -> t -> Prop := | le_refl : forall x, le x x | le_trans : forall x y z, le x y -> le y z -> le x z | le_A_B : le A B | le_B_C : le B C. Definition leb (x y : t) : bool := match x, y with | A, _ => true | _, C => true | B, B => true | _, _ => false end.forall x y : t, le x y <-> leb x y = trueforall x y : t, le x y <-> leb x y = truex, y: tle x y <-> leb x y = truex, y: t
H: le x yleb x y = truex, y: t
H: leb x y = truele x yinduction H; destruct_ts; simpl in *; congruence.x, y: t
H: le x yleb x y = truedestruct_ts; eauto using le; simpl in *; congruence. Qed.x, y: t
H: leb x y = truele x yforall x y : t, le x y -> le y x -> x = yforall x y : t, le x y -> le y x -> x = yx, y: t
H1: le x y
H2: le y xx = ydestruct x, y; simpl in *; congruence. Qed.x, y: t
H1: leb x y = true
H2: leb y x = truex = yforall x y : t, {le x y} + {~ le x y}x, y: t{le x y} + {~ le x y}{le B A} + {~ le B A}{le C A} + {~ le C A}{le C B} + {~ le C B}{le B A} + {~ le B A}~ le B AH: le B AFalsey: t
H0: le B y
H1: le y AFalsedestruct y; simpl in *; congruence.y: t
H0: leb B y = true
H1: leb y A = trueFalse{le C A} + {~ le C A}~ le C AH: le C AFalsey: t
H0: le C y
H1: le y AFalsedestruct y; simpl in *; congruence.y: t
H0: leb C y = true
H1: leb y A = trueFalse{le C B} + {~ le C B}~ le C BH: le C BFalsey: t
H0: le C y
H1: le y BFalsedestruct y; simpl in *; congruence. Qed.y: t
H0: leb C y = true
H1: leb y B = trueFalse
Context
I am trying to define the partial order A <= B <= C with a relation le in Coq and prove that it is decidable: forall x y, {le x y} + {~le x y}.
I succeeded to do it through an equivalent boolean function leb but cannot find a way to prove it directly (or le_antisym for that mater). I get stuck in situations like the following:
Questions
How can I prove, that le B A is a false premise?
Is there an other other proof strategy that I should use?
Should I define my predicate le differently?
Answer
I'd also go with Arthur's solution. But let me demonstrate another approach.
First, we'll need a couple of supporting lemmas:
x: tx <> A -> ~ le x Aremember A; intros; induction 1; subst; firstorder congruence. Qed.x: tx <> A -> ~ le x Ax: tx <> C -> ~ le C xremember C; intros; induction 1; subst; firstorder congruence. Qed.x: tx <> C -> ~ le C x
Now we can define le_dec:
x, y: t{le x y} + {~ le x y}x, y: t{le x y} + {~ le x y}{le A C} + {~ le A C}{le B A} + {~ le B A}{le C A} + {~ le C A}{le C B} + {~ le C B}left; abstract (eapply le_trans; constructor).{le A C} + {~ le A C}right; abstract now apply not_leXA.{le B A} + {~ le B A}right; abstract now apply not_leCX.{le C A} + {~ le C A}right; abstract now apply not_leCX. Defined.{le C B} + {~ le C B}
Notice that I used Defined instead of Qed -- now you can calculate with le_dec, which is usually the point of using the sumbool type.
I also used abstract to conceal the proof terms from the evaluator. E.g. let's imagine I defined a le_dec' function which is the same as le_dec, but with all abstract removed, then we would get the following results when trying to compute le_dec B A / le_dec' B A:
and