Search code examples
coq

Case construct for Coq development


It seems that at some point there was a file SfLib.v that was used for the Software Foundations course. However, the case command proposed in this file is not getting through in my case:

Require Omega.   (* needed for using the [omega] tactic *)
Require Export Bool.
Require Export List.
Require Export Arith.
Require Export Arith.EqNat.  (* Contains [beq_nat], among other things *)

(** * From Basics.v *)

Require String. Open Scope string_scope.

Ltac move_to_top x :=
  match reverse goal with
  | H : _ |- _ => try move x after H
  end.

Tactic Notation "assert_eq" ident(x) constr(v) :=
  let H := fresh in
  assert (x = v) as H by reflexivity;
  clear H.

Tactic Notation "Case_aux" ident(x) constr(name) :=
  first [
    set (x := name); move_to_top x
  | assert_eq x name; move_to_top x
  | fail 1 "because we are working on a different case" ].

Tactic Notation "Case" constr(name) := Case_aux Case name.
Tactic Notation "SCase" constr(name) := Case_aux SCase name.
Tactic Notation "SSCase" constr(name) := Case_aux SSCase name.
Tactic Notation "SSSCase" constr(name) := Case_aux SSSCase name.
Tactic Notation "SSSSCase" constr(name) := Case_aux SSSSCase name.
Tactic Notation "SSSSSCase" constr(name) := Case_aux SSSSSCase name.
Tactic Notation "SSSSSSCase" constr(name) := Case_aux SSSSSSCase name.
Tactic Notation "SSSSSSSCase" constr(name) := Case_aux SSSSSSSCase name.

Fixpoint ble_nat (n m : nat) : bool :=
  match n with
  | O => true
  | S n' =>
      match m with
      | O => false
      | S m' => ble_nat n' m'
      end
  end.

Theorem andb_true_elim1 : forall b c,
  andb b c = true -> b = true.
Proof.
  intros b c H.
  destruct b.
  Case "b = true".
    reflexivity.
  Case "b = false".
    rewrite <- H. reflexivity.  Qed.

In the first case, I'm getting No interpretation for string "b = true".

This was previously addressed in coq error when trying to use Case. Example from Software Foundations book. However, the solution there does no longer work. Should I get rid of all the case statements?


Solution

  • Maybe something changed since then, but now we need to Import notations.

    (* 8.9, 8.10, and newer *)
    From Coq Require String.
    Export String.StringSyntax.  (* [Export] means to [Import] the StringSyntax module, but also make it automatically available to whoever imports this file as well. *)
    Open Scope string_scope.
    
    (* 8.8 and older (still works with 8.9, 8.10, but pollutes the namespace) *)
    From Coq Require Export String.
    Open Scope string_scope.
    

    However, as evidenced by the removal of the module, the benefit of this trick is quite minor. Most people just use bullets, with comments to indicate the cases if they even care to comment.


    Above, Open Scope is used, which may be fine for self-contained projects like SF, but for big and open projects, to avoid surprises with notations, I would recommend only using Local Open Scope (which then needs to appear in every file), or keeping Open Scope inside inner modules (that still need to be imported explicitly, but can be reexported together with others).