Library Scat.Conditions
Syntax and semantics of conditions
Conditions are zeroth order formula used as boolean expressions in programsRequire Export ZArith.
Require Export ZArith_dec.
Require Export String.
Require Import PArith.
Require Import PArith.POrderedType.
Require Export MiscUtils.
Open Scope Z_scope.
Inductive binop : Set := PLUS | MINUS | MULT | DIV.
Definition evalop (op: binop) : Z → Z → Z
:= match op with PLUS ⇒ Zplus | MINUS ⇒ Zminus | MULT ⇒ Zmult | DIV ⇒ Zdiv end.
An abstract type of values: useful to avoid computations on values during proofs.
Module Type ValueTypeAbstraction.
Parameter value: Set.
Parameter vcte: Z → value.
Parameter Zof: value → Z.
Parameter Zof_vcte: ∀ z, Zof (vcte z) = z.
Parameter vcte_Zof: ∀ v, vcte (Zof v) = v.
Parameter vbin: binop → value → value → value.
Parameter Zof_vbin: ∀ op v1 v2, Zof (vbin op v1 v2) = evalop op (Zof v1) (Zof v2).
End ValueTypeAbstraction.
Module Value: ValueTypeAbstraction.
Definition value := Z.
Definition vcte := fun (x:Z) ⇒ x.
Definition Zof := vcte.
Definition vbin := evalop.
Lemma Zof_vcte: ∀ z, Zof (vcte z) = z.
Proof.
auto.
Qed.
Lemma vcte_Zof: ∀ v, vcte (Zof v) = v.
Proof.
auto.
Qed.
Lemma Zof_vbin: ∀ op v1 v2, Zof (vbin op v1 v2) = evalop op (Zof v1) (Zof v2).
Proof.
auto.
Qed.
End Value.
Export Value.
Lemma Zof_intro v1 v2: Zof v1 = Zof v2 → v1 = v2.
Proof.
intros; rewrite <- (vcte_Zof v1). rewrite <- (vcte_Zof v2).
eqtriv.
Qed.
Hint Rewrite Zof_vcte Zof_vbin: zof_value.
Inductive vle (n1 n2: value): Prop :=
| vlecons: (Zof n1) ≤ (Zof n2) → vle n1 n2.
Below, each ctefun x (with x:positive) represents a symbol of unary function.
(e.g. an unidimensional constant array)
We may reason on such an array by using axioms...
Parameter ctefun: positive → value → value.
Lemma ctefun_Zof (x:positive) (v: value): ctefun x v = ctefun x (vcte (Zof v)).
Proof.
rewrite vcte_Zof.
auto.
Qed.
Lemma ctefun_Zof (x:positive) (v: value): ctefun x v = ctefun x (vcte (Zof v)).
Proof.
rewrite vcte_Zof.
auto.
Qed.
this is for pretty-printing only
identifier of the variable
}.
Inductive term: Set :=
| tvar (x: var)
| tcte (c: Z)
| tbin (op: binop) (tl tr: term)
| told (t:term)
| tapp (f:var) (t:term).
Coercion tvar: var >-> term.
Coercion tcte: Z >-> term.
Inductive term: Set :=
| tvar (x: var)
| tcte (c: Z)
| tbin (op: binop) (tl tr: term)
| told (t:term)
| tapp (f:var) (t:term).
Coercion tvar: var >-> term.
Coercion tcte: Z >-> term.
Definition state := positive → value.
Fixpoint teval (t:term) (s: state) : value :=
match t with
| tvar x ⇒ s (vid x)
| tcte c ⇒ vcte c
| tbin op tl tr ⇒ vbin op (teval tl s) (teval tr s)
| told t ⇒ teval t s
| tapp f t ⇒ ctefun (vid f) (teval t s)
end.
Definition ext (s s': state) := ∀ x, s x = s' x.
Lemma ext_teval (t: term): ∀ s s',
ext s s' →
teval t s = teval t s'.
Proof.
induction t; simpl; intuition.
erewrite IHt1; eauto.
erewrite IHt2; eauto.
erewrite IHt; eauto.
Qed.
Fixpoint teval (t:term) (s: state) : value :=
match t with
| tvar x ⇒ s (vid x)
| tcte c ⇒ vcte c
| tbin op tl tr ⇒ vbin op (teval tl s) (teval tr s)
| told t ⇒ teval t s
| tapp f t ⇒ ctefun (vid f) (teval t s)
end.
Definition ext (s s': state) := ∀ x, s x = s' x.
Lemma ext_teval (t: term): ∀ s s',
ext s s' →
teval t s = teval t s'.
Proof.
induction t; simpl; intuition.
erewrite IHt1; eauto.
erewrite IHt2; eauto.
erewrite IHt; eauto.
Qed.
Definition add (x: positive) (val:value) (s: state) : state
:= fun x' ⇒ if Positive_as_DT.eq_dec x x' then val else (s x').
Lemma add_in x val s: add x val s x = val.
Proof.
unfold add.
case (Positive_as_DT.eq_dec x x); tauto.
Qed.
Hint Resolve add_in: checker.
Lemma add_out x val s x': (Zpos x)<>(Zpos x') → add x val s x' = s x'.
Proof.
unfold add; case (Positive_as_DT.eq_dec x x'); try (intros; subst; tauto).
Qed.
Hint Resolve add_out: checker.
Lemma add_out2 x val s x': x≠x' → add x val s x' = s x'.
Proof.
unfold add; case (Positive_as_DT.eq_dec x x'); try (intros; subst; tauto).
Qed.
Hint Resolve add_out2: checker.
Lemma add_id x y s: add x (s x) s y = s y.
Proof.
unfold add; intros. case (Positive_as_DT.eq_dec x y); auto.
intros H; inversion_clear H; auto.
Qed.
Hint Rewrite add_id: rchecker.
:= fun x' ⇒ if Positive_as_DT.eq_dec x x' then val else (s x').
Lemma add_in x val s: add x val s x = val.
Proof.
unfold add.
case (Positive_as_DT.eq_dec x x); tauto.
Qed.
Hint Resolve add_in: checker.
Lemma add_out x val s x': (Zpos x)<>(Zpos x') → add x val s x' = s x'.
Proof.
unfold add; case (Positive_as_DT.eq_dec x x'); try (intros; subst; tauto).
Qed.
Hint Resolve add_out: checker.
Lemma add_out2 x val s x': x≠x' → add x val s x' = s x'.
Proof.
unfold add; case (Positive_as_DT.eq_dec x x'); try (intros; subst; tauto).
Qed.
Hint Resolve add_out2: checker.
Lemma add_id x y s: add x (s x) s y = s y.
Proof.
unfold add; intros. case (Positive_as_DT.eq_dec x y); auto.
intros H; inversion_clear H; auto.
Qed.
Hint Rewrite add_id: rchecker.
Inductive bincmp : Set := LE | EQ.
Definition evalcmp (cmp: bincmp): value → value → Prop
:= match cmp with LE ⇒ vle | EQ ⇒ @eq value end.
Inductive binlog: Set := AND | OR.
Definition evallog (og: binlog) : Prop → Prop → Prop
:= if og then and else or.
Inductive cond: Set :=
| basic (b: bool)
| atom (oc: bincmp) (tl tr: term)
| bin (og: binlog) (cl cr: cond)
| not (c: cond).
Definition ceq (x:var) (t:term) := atom EQ (tvar x) t.
Definition tauto := basic true.
Definition absurd := basic false.
Definition evalcmp (cmp: bincmp): value → value → Prop
:= match cmp with LE ⇒ vle | EQ ⇒ @eq value end.
Inductive binlog: Set := AND | OR.
Definition evallog (og: binlog) : Prop → Prop → Prop
:= if og then and else or.
Inductive cond: Set :=
| basic (b: bool)
| atom (oc: bincmp) (tl tr: term)
| bin (og: binlog) (cl cr: cond)
| not (c: cond).
Definition ceq (x:var) (t:term) := atom EQ (tvar x) t.
Definition tauto := basic true.
Definition absurd := basic false.
Fixpoint eval (c:cond) (s: state): Prop :=
match c with
| basic b ⇒ Is_true b
| atom oc tl tr ⇒ evalcmp oc (teval tl s) (teval tr s)
| bin og cl cr ⇒ evallog og (eval cl s) (eval cr s)
| not c ⇒ ~(eval c s)
end.
Lemma ext_eval c: ∀ s s',
ext s s' →
eval c s = eval c s'.
Proof.
induction c; simpl; intuition.
erewrite ext_teval; eauto.
erewrite ext_teval with (s:=s); eauto.
erewrite IHc1; eauto.
erewrite IHc2; eauto.
erewrite IHc; eauto.
Qed.
match c with
| basic b ⇒ Is_true b
| atom oc tl tr ⇒ evalcmp oc (teval tl s) (teval tr s)
| bin og cl cr ⇒ evallog og (eval cl s) (eval cr s)
| not c ⇒ ~(eval c s)
end.
Lemma ext_eval c: ∀ s s',
ext s s' →
eval c s = eval c s'.
Proof.
induction c; simpl; intuition.
erewrite ext_teval; eauto.
erewrite ext_teval with (s:=s); eauto.
erewrite IHc1; eauto.
erewrite IHc2; eauto.
erewrite IHc; eauto.
Qed.
Semantics of told
Fixpoint oteval (t:term) (old new: state) : value :=
match t with
| tvar x ⇒ new (vid x)
| tcte c ⇒ vcte c
| tbin op tl tr ⇒ vbin op (oteval tl old new) (oteval tr old new)
| told t ⇒ teval t old
| tapp f t ⇒ ctefun (vid f) (oteval t old new)
end.
Lemma oteval_teval t s: oteval t s s = teval t s.
Proof.
induction t; simpl; congruence.
Qed.
Hint Rewrite oteval_teval: rchecker.
Fixpoint oeval (c:cond) (old new: state): Prop :=
match c with
| basic b ⇒ Is_true b
| atom oc tl tr ⇒ evalcmp oc (oteval tl old new) (oteval tr old new)
| bin og cl cr ⇒ evallog og (oeval cl old new) (oeval cr old new)
| not c ⇒ ~(oeval c old new)
end.
Lemma oeval_eval c s: oeval c s s = eval c s.
Proof.
induction c; simpl; autorewrite with rchecker; try congruence.
Qed.
Hint Rewrite oeval_eval: rchecker.
lframeeq l s s' indicates that only variables in the frame l (a list of variables)
may have changed between states s and s'.
Open Scope list_scope.
Fixpoint labsent (x:positive) (l: list var) : Prop :=
match l with
| nil ⇒ True
| y::l ⇒ x<>(vid y) ∧ (labsent x l)
end.
Definition lframeeq (l:list var) (s s': state) : Prop
:= ∀ x, labsent x l → (s x)=(s' x).
Hint Unfold lframeeq: checker.
Fixpoint labsent (x:positive) (l: list var) : Prop :=
match l with
| nil ⇒ True
| y::l ⇒ x<>(vid y) ∧ (labsent x l)
end.
Definition lframeeq (l:list var) (s s': state) : Prop
:= ∀ x, labsent x l → (s x)=(s' x).
Hint Unfold lframeeq: checker.
Definition binop_eq (x y: binop) :=
match x,y with
| PLUS, PLUS ⇒ true
| MINUS, MINUS ⇒ true
| MULT, MULT ⇒ true
| DIV, DIV ⇒ true
| _,_ ⇒ false
end.
Lemma binop_eq_eq x y: binop_eq x y=true → x=y.
Proof.
decide_eqb_eq x y.
Qed.
Hint Resolve binop_eq_eq: eqtrue.
NB: lemma only used here to check binop_eq
Lemma binop_eq_refl x: binop_eq x x=true.
Proof.
destruct x; simpl; auto.
Qed.
Definition var_eq (x1 x2: var) := Peqb (vid x1) (vid x2).
Lemma var_eq_eq x y: var_eq x y = true → (vid x)=(vid y).
Proof.
unfold var_eq; eqtrue.
Qed.
Hint Resolve var_eq_eq: eqtrue.
Fixpoint term_eq (t1 t2: term) :=
match t1,t2 with
| tvar x1, tvar x2 ⇒ var_eq x1 x2
| tcte c1, tcte c2 ⇒ Zeq_bool c1 c2
| tbin op1 tl1 tr1, tbin op2 tl2 tr2 ⇒
binop_eq op1 op2 &&& term_eq tl1 tl2 &&& term_eq tr1 tr2
| told t1, told t2 ⇒ term_eq t1 t2
| tapp f1 t1, tapp f2 t2 ⇒ var_eq f1 f2 &&& term_eq t1 t2
| _, _ ⇒ false
end.
Lemma term_eq_eval t1 t2 s: term_eq t1 t2 = true → teval t1 s=teval t2 s.
Proof.
decide_eqb_eq t1 t2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve term_eq_eval: eqtrue.
Lemma term_eq_oeval t1 t2 old s: term_eq t1 t2 = true → oteval t1 old s=oteval t2 old s.
Proof.
decide_eqb_eq t1 t2; eqtrue; simpl; intros; eqtriv.
Qed.
Hint Resolve term_eq_oeval: eqtrue.
Definition bincmp_eq (x y: bincmp) :=
match x,y with
| LE, LE ⇒ true
| EQ, EQ ⇒ true
| _,_ ⇒ false
end.
Lemma bincmp_eq_eq x y: bincmp_eq x y=true → x=y.
Proof.
decide_eqb_eq x y.
Qed.
Hint Resolve bincmp_eq_eq: eqtrue.
Proof.
destruct x; simpl; auto.
Qed.
Definition var_eq (x1 x2: var) := Peqb (vid x1) (vid x2).
Lemma var_eq_eq x y: var_eq x y = true → (vid x)=(vid y).
Proof.
unfold var_eq; eqtrue.
Qed.
Hint Resolve var_eq_eq: eqtrue.
Fixpoint term_eq (t1 t2: term) :=
match t1,t2 with
| tvar x1, tvar x2 ⇒ var_eq x1 x2
| tcte c1, tcte c2 ⇒ Zeq_bool c1 c2
| tbin op1 tl1 tr1, tbin op2 tl2 tr2 ⇒
binop_eq op1 op2 &&& term_eq tl1 tl2 &&& term_eq tr1 tr2
| told t1, told t2 ⇒ term_eq t1 t2
| tapp f1 t1, tapp f2 t2 ⇒ var_eq f1 f2 &&& term_eq t1 t2
| _, _ ⇒ false
end.
Lemma term_eq_eval t1 t2 s: term_eq t1 t2 = true → teval t1 s=teval t2 s.
Proof.
decide_eqb_eq t1 t2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve term_eq_eval: eqtrue.
Lemma term_eq_oeval t1 t2 old s: term_eq t1 t2 = true → oteval t1 old s=oteval t2 old s.
Proof.
decide_eqb_eq t1 t2; eqtrue; simpl; intros; eqtriv.
Qed.
Hint Resolve term_eq_oeval: eqtrue.
Definition bincmp_eq (x y: bincmp) :=
match x,y with
| LE, LE ⇒ true
| EQ, EQ ⇒ true
| _,_ ⇒ false
end.
Lemma bincmp_eq_eq x y: bincmp_eq x y=true → x=y.
Proof.
decide_eqb_eq x y.
Qed.
Hint Resolve bincmp_eq_eq: eqtrue.
NB: lemma only used here to check bincmp_eq
Lemma bincmp_eq_refl x: bincmp_eq x x=true.
Proof.
destruct x; simpl; auto.
Qed.
Definition binlog_eq (x y: binlog) :=
match x,y with
| AND, AND ⇒ true
| OR, OR ⇒ true
| _,_ ⇒ false
end.
Lemma binlog_eq_eq x y: binlog_eq x y=true → x=y.
Proof.
decide_eqb_eq x y.
Qed.
Hint Resolve binlog_eq_eq: eqtrue.
Proof.
destruct x; simpl; auto.
Qed.
Definition binlog_eq (x y: binlog) :=
match x,y with
| AND, AND ⇒ true
| OR, OR ⇒ true
| _,_ ⇒ false
end.
Lemma binlog_eq_eq x y: binlog_eq x y=true → x=y.
Proof.
decide_eqb_eq x y.
Qed.
Hint Resolve binlog_eq_eq: eqtrue.
NB: lemma only used here to check binlog_eq
Lemma binlog_eq_refl x: binlog_eq x x=true.
Proof.
destruct x; simpl; auto.
Qed.
Fixpoint cond_eq (c1 c2: cond) :=
match c1, c2 with
| basic b1, basic b2 ⇒ eqb b1 b2
| atom oc1 tl1 tr1, atom oc2 tl2 tr2 ⇒
bincmp_eq oc1 oc2 &&&
term_eq tl1 tl2 &&&
term_eq tr1 tr2
| bin og1 cl1 cr1, bin og2 cl2 cr2 ⇒
binlog_eq og1 og2 &&&
cond_eq cl1 cl2 &&&
cond_eq cr1 cr2
| not c1, not c2 ⇒ cond_eq c1 c2
| _, _ ⇒ false
end.
Lemma cond_eq_eval c1 c2 s: cond_eq c1 c2 = true → eval c1 s=eval c2 s.
Proof.
decide_eqb_eq c1 c2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve cond_eq_eval: eqtrue.
Lemma cond_eq_oeval c1 c2 old s: cond_eq c1 c2 = true → oeval c1 old s=oeval c2 old s.
Proof.
decide_eqb_eq c1 c2; eqtrue; simpl; intros; eqtriv.
Qed.
Hint Resolve cond_eq_oeval: eqtrue.
Proof.
destruct x; simpl; auto.
Qed.
Fixpoint cond_eq (c1 c2: cond) :=
match c1, c2 with
| basic b1, basic b2 ⇒ eqb b1 b2
| atom oc1 tl1 tr1, atom oc2 tl2 tr2 ⇒
bincmp_eq oc1 oc2 &&&
term_eq tl1 tl2 &&&
term_eq tr1 tr2
| bin og1 cl1 cr1, bin og2 cl2 cr2 ⇒
binlog_eq og1 og2 &&&
cond_eq cl1 cl2 &&&
cond_eq cr1 cr2
| not c1, not c2 ⇒ cond_eq c1 c2
| _, _ ⇒ false
end.
Lemma cond_eq_eval c1 c2 s: cond_eq c1 c2 = true → eval c1 s=eval c2 s.
Proof.
decide_eqb_eq c1 c2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve cond_eq_eval: eqtrue.
Lemma cond_eq_oeval c1 c2 old s: cond_eq c1 c2 = true → oeval c1 old s=oeval c2 old s.
Proof.
decide_eqb_eq c1 c2; eqtrue; simpl; intros; eqtriv.
Qed.
Hint Resolve cond_eq_oeval: eqtrue.
Fixpoint lvar_eq (l1 l2: list var) :=
match l1, l2 with
| nil, nil ⇒ true
| x1::l1, x2::l2 ⇒ var_eq x1 x2 &&& lvar_eq l1 l2
| _, _ ⇒ false
end.
Lemma lvar_eq_labsent l1 l2 x: lvar_eq l1 l2 = true → labsent x l1=labsent x l2.
Proof.
decide_eqb_eq l1 l2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve lvar_eq_labsent: eqtrue.
Lemma lvar_eq_lframeeq l1 l2 s s':
lvar_eq l1 l2 = true → lframeeq l2 s s' → lframeeq l1 s s'.
Proof.
unfold lframeeq. intros H H0 x H1. apply H0; erewrite <- lvar_eq_labsent; eauto.
Qed.
Hint Resolve lvar_eq_lframeeq: eqtrue.
match l1, l2 with
| nil, nil ⇒ true
| x1::l1, x2::l2 ⇒ var_eq x1 x2 &&& lvar_eq l1 l2
| _, _ ⇒ false
end.
Lemma lvar_eq_labsent l1 l2 x: lvar_eq l1 l2 = true → labsent x l1=labsent x l2.
Proof.
decide_eqb_eq l1 l2; eqtrue; intros; eqtriv.
Qed.
Hint Resolve lvar_eq_labsent: eqtrue.
Lemma lvar_eq_lframeeq l1 l2 s s':
lvar_eq l1 l2 = true → lframeeq l2 s s' → lframeeq l1 s s'.
Proof.
unfold lframeeq. intros H H0 x H1. apply H0; erewrite <- lvar_eq_labsent; eauto.
Qed.
Hint Resolve lvar_eq_lframeeq: eqtrue.
Fixpoint tsubst (t:term) (x: positive) t2: term :=
match t with
| tvar x' ⇒ if Positive_as_DT.eq_dec x (vid x') then t2 else t
| tcte c ⇒ t
| tbin op tl tr ⇒ tbin op (tsubst tl x t2) (tsubst tr x t2)
| told t ⇒ tsubst t x t2
| tapp f t ⇒ tapp f (tsubst t x t2)
end.
Lemma tsubst_teval t x t2 s:
teval (tsubst t x t2) s = teval t (add x (teval t2 s) s).
Proof.
induction t; simpl; auto.
unfold add; case (Positive_as_DT.eq_dec x (vid x0)); simpl; auto.
rewrite IHt1; rewrite IHt2; auto.
rewrite IHt; auto.
Qed.
match t with
| tvar x' ⇒ if Positive_as_DT.eq_dec x (vid x') then t2 else t
| tcte c ⇒ t
| tbin op tl tr ⇒ tbin op (tsubst tl x t2) (tsubst tr x t2)
| told t ⇒ tsubst t x t2
| tapp f t ⇒ tapp f (tsubst t x t2)
end.
Lemma tsubst_teval t x t2 s:
teval (tsubst t x t2) s = teval t (add x (teval t2 s) s).
Proof.
induction t; simpl; auto.
unfold add; case (Positive_as_DT.eq_dec x (vid x0)); simpl; auto.
rewrite IHt1; rewrite IHt2; auto.
rewrite IHt; auto.
Qed.