coqnested-ifcoq-tactic

Is there a three-valued case analysis on patterns (a < b) (a = b) (a > b)?


I want my students to prove some stuff overs Binary Search Trees. Most of the proofs require to perform a case analysis on some arithmetic inequality over three cases:

To do that i've written a kind of ugly tactic that checks if the goal contains nested ifs that correspond to these three cases:

(* This is some syntactic sugar for nested if like:
   if a <? b then      (* adds hypothesis a<?b *)
   else if a >? b then (* adds hypothesis b<?a *)
   else                (* adds hypothesis a=b *) *)
Ltac case_ineq :=
  match goal with
  | [ |- context[if ?X <? ?Y then _ else if ?Y <? ?X then _ else _ ]] =>
      case_eq (X <? Y); intros;
      [> | case_eq (Y <? X); intros;
           [> | assert (X = Y);
                only 1 : (apply not_lt_nor_gt_is_eq; assumption)]]
  end.

Where not_lt_nor_gt_is_eq is an auxilliary lemma i've proven by myself stated as follows (the proof is irrelevant):

Lemma not_lt_nor_gt_is_eq : forall x k,
  (x <? k) = false -> (k <? x) = false <-> x = k.

I'am not entirely satisfied with this solution as it is very sensitive to how students will write code, and its also too long to my taste.

So my question is:


Solution

  • The lt_eq_lt_dec function from the Arith library returns a sum type that represents three possible cases: a < b, a = b, or a > b.

    Require Import Arith String.
    
    Definition three_valued_case_analysis (a b : nat) : string :=
      match lt_eq_lt_dec a b with
      | inleft (left _) => "a < b"
      | inleft (right _) => "a = b"
      | inright _ => "a > b"
      end.