Library prog


Based on some ideas and some code of tutorial on Coq by Pierce and al. Software Foundations. The license of the software is not strict, but the license must be included, cf. SF-LICENSE.

This file defines the language used, namely arithmetic expressions aexp, boolean expressions bexp, statements stmt and programs prog.

Require Export sflib.

Inductive id : Type :=
  Id : nat id.

Lemma eq_id_dec : (i1 i2:id),
  {i1 = i2} + {i1 i2}.
Proof.
  intros. destruct i1, i2.
  destruct (Nat.eq_dec n n0).
  left; subst; reflexivity.
  right. injection. assumption.
Defined.

Inductive aexp : Type :=
  | A_num : nat aexp
  | A_id : id aexp
  | A_plus : aexp aexp aexp
  | A_minus : aexp aexp aexp
  | A_mult : aexp aexp aexp.

Tactic Notation "aexp_cases" tactic(first) ident(c) :=
  first;
  [ Case_aux c "A_num" | Case_aux c "A_id" | Case_aux c "A_plus"
  | Case_aux c "A_minus" | Case_aux c "A_mult" ].

Inductive id_inR_aexp : aexp id Prop :=
  | IIA_id : i, id_inR_aexp (A_id i) i
  | IIA_plus_l : i, a1 a2, id_inR_aexp a1 i
      id_inR_aexp (A_plus a1 a2) i
  | IIA_plus_r : i, a1 a2, id_inR_aexp a2 i
      id_inR_aexp (A_plus a1 a2) i
  | IIA_minus_l : i, a1 a2, id_inR_aexp a1 i
      id_inR_aexp (A_minus a1 a2) i
  | IIA_minus_r : i, a1 a2, id_inR_aexp a2 i
      id_inR_aexp (A_minus a1 a2) i
  | IIA_mult_l : i, a1 a2, id_inR_aexp a1 i
      id_inR_aexp (A_mult a1 a2) i
  | IIA_mult_r : i, a1 a2, id_inR_aexp a2 i
      id_inR_aexp (A_mult a1 a2) i.

Inductive bexp : Type :=
  | B_true : bexp
  | B_false : bexp
  | B_eq : aexp aexp bexp
  | B_le : aexp aexp bexp
  | B_not : bexp bexp
  | B_and : bexp bexp bexp.

Tactic Notation "bexp_cases" tactic(first) ident(c) :=
  first;
  [ Case_aux c "B_true" | Case_aux c "B_false" | Case_aux c "B_eq"
  | Case_aux c "B_le" | Case_aux c "B_not" | Case_aux c "B_and" ].

Inductive id_inR_bexp : bexp id Prop :=
  | IIB_eq_l : a1 a2 i, id_inR_aexp a1 i id_inR_bexp (B_eq a1 a2) i
  | IIB_eq_r : a1 a2 i, id_inR_aexp a2 i id_inR_bexp (B_eq a1 a2) i
  | IIB_le_l : a1 a2 i, id_inR_aexp a1 i id_inR_bexp (B_le a1 a2) i
  | IIB_le_r : a1 a2 i, id_inR_aexp a2 i id_inR_bexp (B_le a1 a2) i
  | IIB_not : b i, id_inR_bexp b i id_inR_bexp (B_not b) i
  | IIB_and_l : b1 b2 i, id_inR_bexp b1 i id_inR_bexp (B_and b1 b2) i
  | IIB_and_r : b1 b2 i, id_inR_bexp b2 i id_inR_bexp (B_and b1 b2) i.

Definition label := nat.

Inductive prog : Type :=
  | P_nil : prog
  | P_cons : stmt prog prog
with stmt :=
  | S_skip : label stmt
  | S_ass : label id aexp stmt
  | S_if : label bexp prog prog stmt
  | S_while : label bexp prog stmt
  | S_assert : label bexp label stmt.

Scheme prog_mutual_ind := Induction for prog Sort Prop
  with stmt_mutual_ind := Induction for stmt Sort Prop.

Scheme prog_mutual_rect := Induction for prog Sort Type
  with stmt_mutual_rect := Induction for stmt Sort Type.

Tactic Notation "prog_cases" tactic(first) ident(c) :=
  first;
  [ Case_aux c "P_nil" | Case_aux c "P_cons" | Case_aux c "S_skip"
  | Case_aux c "S_ass" | Case_aux c "S_ifb" | Case_aux c "S_while"
  | Case_aux c "S_assert" ].

Notation "'SKIP' << l >>" :=
  (S_skip l) (at level 60).
Notation "x '::=' a << l >>" :=
  (S_ass l x a) (at level 60).
Notation "'WHILE' << l >> b 'DO' c 'END'" :=
  (S_while l b c) (at level 80, right associativity).
Notation "'IFB' << l >> b 'THEN' c2 'ELSE' c3 'FI'" :=
  (S_if l b c2 c3) (at level 80, right associativity).
Notation "'ASSERT' << l >> b =>> l1" :=
  (S_assert l b l1) (at level 80, right associativity).

Notation "s ;; p" := (P_cons s p)
                     (at level 60, right associativity).
Notation "{{ }}" := P_nil.
Notation "{{ p ; .. ; q }}" := (P_cons p .. (P_cons q {{}}) ..).

Fixpoint app_prog (p1 p2 : prog) :=
  match p1 with
  | {{}}p2
  | s;;ps;;(app_prog p p2)
  end.

Notation "x +;+ y" := (app_prog x y)
                      (right associativity, at level 60).