aboutsummaryrefslogtreecommitdiffstats
path: root/mppa_k1c/abstractbb/ImpDep.v
diff options
context:
space:
mode:
Diffstat (limited to 'mppa_k1c/abstractbb/ImpDep.v')
-rw-r--r--mppa_k1c/abstractbb/ImpDep.v264
1 files changed, 149 insertions, 115 deletions
diff --git a/mppa_k1c/abstractbb/ImpDep.v b/mppa_k1c/abstractbb/ImpDep.v
index 2e2ad40f..3efe6a36 100644
--- a/mppa_k1c/abstractbb/ImpDep.v
+++ b/mppa_k1c/abstractbb/ImpDep.v
@@ -72,8 +72,6 @@ Hypothesis hC_tree_correct: forall t, WHEN hC_tree t ~> t' THEN pre_data t=data
Variable hC_list_tree: pre_hashV list_tree -> ?? hashV list_tree.
Hypothesis hC_list_tree_correct: forall t, WHEN hC_list_tree t ~> t' THEN pre_data t=data t'.
-Variable ge: genv.
-
(* First, we wrap constructors for hashed values !*)
Local Open Scope positive.
@@ -107,19 +105,6 @@ Qed.
Global Opaque hTop.
Hint Resolve hTop_correct: wlp.
-Definition hTerase (t1 t2: hashV tree) (debug: option pstring): ?? hashV tree :=
- DO hc <~ hash 3;;
- hC_tree {| pre_data:=Terase (data t1) (data t2);
- hcodes:=[hc;hid t1; hid t2]; debug_info := debug |}.
-
-Lemma hTerase_correct t1 t2 dbg:
- WHEN hTerase t1 t2 dbg ~> t THEN (data t)=(Terase (data t1) (data t2)).
-Proof.
- wlp_simplify.
-Qed.
-Global Opaque hTerase.
-Hint Resolve hTerase_correct: wlp.
-
Definition hTnil (_: unit): ?? hashV list_tree :=
hC_list_tree {| pre_data:=Tnil; hcodes := nil; debug_info := None |} .
@@ -146,7 +131,9 @@ Hint Resolve hTcons_correct: wlp.
(* Second, we use these hashed constructors ! *)
-Definition hdeps:= Dict.t (hashV tree).
+Record hdeps:= {hpre: list (hashV tree); hpost: Dict.t (hashV tree)}.
+
+Coercion hpost: hdeps >-> Dict.t.
(* pseudo deps_get *)
Definition pdeps_get (d:hdeps) x : tree :=
@@ -169,6 +156,12 @@ Qed.
Global Opaque hdeps_get.
Hint Resolve hdeps_get_correct: wlp.
+Definition hdeps_valid ge (hd:hdeps) m := forall ht, List.In ht hd.(hpre) -> tree_eval ge (data ht) m <> None.
+
+Definition deps_model ge (d: deps) (hd:hdeps): Prop :=
+ (forall m, hdeps_valid ge hd m <-> pre d ge m)
+ /\ (forall m x, tree_eval ge (pdeps_get hd x) m = deps_eval ge d x m).
+
Fixpoint hexp_tree (e: exp) (d od: hdeps) (dbg: option pstring) : ?? hashV tree :=
match e with
| PReg x => hdeps_get d x dbg
@@ -187,86 +180,95 @@ with hlist_exp_tree (le: list_exp) (d od: hdeps): ?? hashV list_tree :=
| LOld le => hlist_exp_tree le od od
end.
-Lemma hexp_tree_correct_x e od1 od2:
- (forall x, pdeps_get od1 x = deps_get od2 x) ->
- forall d1 d2 dbg,
- (forall x, pdeps_get d1 x = deps_get d2 x) ->
- WHEN hexp_tree e d1 od1 dbg ~> t THEN data t = exp_tree e d2 od2.
+Lemma hexp_tree_correct_x ge e hod od:
+ deps_model ge od hod ->
+ forall hd d dbg,
+ deps_model ge d hd ->
+ WHEN hexp_tree e hd hod dbg ~> t THEN forall m, tree_eval ge (data t) m = tree_eval ge (exp_tree e d od) m.
Proof.
intro H.
- induction e using exp_mut with (P0:=fun le => forall d1 d2,
- (forall x, pdeps_get d1 x = deps_get d2 x) ->
- WHEN hlist_exp_tree le d1 od1 ~> lt THEN data lt = list_exp_tree le d2 od2); simpl; wlp_simplify; congruence.
+ induction e using exp_mut with (P0:=fun le => forall d hd,
+ deps_model ge d hd ->
+ WHEN hlist_exp_tree le hd hod ~> lt THEN forall m, list_tree_eval ge (data lt) m = list_tree_eval ge (list_exp_tree le d od) m);
+ unfold deps_model, deps_eval in * |- * ; simpl; wlp_simplify; try congruence.
+ - rewrite H4, <- H0; simpl; reflexivity.
+ - rewrite H1; simpl; reflexivity.
+ - rewrite H5, <- H0, <- H4; simpl; reflexivity.
Qed.
Global Opaque hexp_tree.
-Lemma hexp_tree_correct e d1 od1 dbg:
- WHEN hexp_tree e d1 od1 dbg ~> t THEN forall od2 d2, (forall x, pdeps_get od1 x = deps_get od2 x) -> (forall x, pdeps_get d1 x = deps_get d2 x) -> data t = exp_tree e d2 od2.
+Lemma hexp_tree_correct e hd hod dbg:
+ WHEN hexp_tree e hd hod dbg ~> t THEN forall ge od d m, deps_model ge od hod -> deps_model ge d hd -> tree_eval ge (data t) m = tree_eval ge (exp_tree e d od) m.
Proof.
- intros t H od2 d2 H1 H2; apply (hexp_tree_correct_x e od1 od2 H1 d1 d2 dbg H2 t H).
+ unfold wlp; intros; eapply hexp_tree_correct_x; eauto.
Qed.
Hint Resolve hexp_tree_correct: wlp.
-Variable debug_assign: R.t -> ?? option pstring.
-
-Fixpoint hinst_deps (i: inst) (d od: hdeps): ?? hdeps :=
- match i with
- | nil => RET d
- | (x, e)::i' =>
- DO dbg <~ debug_assign x;;
- DO t0 <~ hdeps_get d x None;;
- DO v' <~ (if failsafe (data t0)
- then
- hexp_tree e d od dbg
- else
- DO t1 <~ hexp_tree e d od None;;
- hTerase t1 t0 dbg);;
- hinst_deps i' (Dict.set d x v') od
+Definition failsafe (t: tree): bool :=
+ match t with
+ | Tname x => true
+ | Top o Tnil => is_constant o
+ | _ => false
end.
-Lemma pset_spec_eq d x t:
- pdeps_get (Dict.set d x t) x = (data t).
-Proof.
- unfold pdeps_get; rewrite Dict.set_spec_eq; simpl; auto.
-Qed.
+Local Hint Resolve is_constant_correct.
-Lemma pset_spec_diff d x y t:
- x <> y -> pdeps_get (Dict.set d x t) y = pdeps_get d y.
+Lemma failsafe_correct ge (t: tree) m: failsafe t = true -> tree_eval ge t m <> None.
Proof.
- unfold pdeps_get; intros; rewrite Dict.set_spec_diff; simpl; auto.
+ destruct t; simpl; try congruence.
+ destruct l; simpl; try congruence.
+ eauto.
Qed.
-
-Lemma pempty_spec x: pdeps_get Dict.empty x = Tname x.
+Local Hint Resolve failsafe_correct.
+
+Definition hdeps_set (d:hdeps) x (t:hashV tree) :=
+ DO ot <~ hdeps_get d x None;;
+ RET {| hpre:=if failsafe (data ot) then d.(hpre) else ot::d.(hpre);
+ hpost:=Dict.set d x t |}.
+
+Lemma hdeps_set_correct hd x ht:
+ WHEN hdeps_set hd x ht ~> nhd THEN
+ forall ge d t, deps_model ge d hd ->
+ (forall m, tree_eval ge (data ht) m = tree_eval ge t m) -> (* TODO: condition à revoir, on peut sans doute relâcher ici ! *)
+ deps_model ge (deps_set d x t) nhd.
Proof.
- unfold pdeps_get; rewrite Dict.empty_spec; simpl; auto.
+ intros; wlp_simplify.
+ unfold deps_model, deps_set; simpl. destruct H0 as (DM0 & DM1); split.
+ - intros m; unfold hdeps_valid in DM0 |- *; simpl.
+ generalize (failsafe_correct ge (data exta) m); intros FAILSAFE.
+ destruct (DM0 m) as (H2 & H3); clear DM0. unfold deps_eval in * |- *.
+ destruct (failsafe _); simpl.
+ * rewrite !H, !DM1 in * |- *; intuition (subst; eauto).
+ * clear FAILSAFE. rewrite <- DM1, <- H. intuition (subst; eauto).
+ - clear H DM0. unfold deps_eval, pdeps_get, deps_get in * |- *; simpl.
+ intros; case (R.eq_dec x x0).
+ + intros; subst; rewrite !Dict.set_spec_eq; simpl; auto.
+ + intros; rewrite !Dict.set_spec_diff; simpl; auto.
Qed.
+Local Hint Resolve hdeps_set_correct: wlp.
+Global Opaque hdeps_set.
-Hint Rewrite pset_spec_eq pempty_spec: dict_rw.
+Variable debug_assign: R.t -> ?? option pstring.
+
+Fixpoint hinst_deps (i: inst) (d od: hdeps): ?? hdeps :=
+ match i with
+ | nil => RET d
+ | (x, e)::i' =>
+ DO dbg <~ debug_assign x;;
+ DO ht <~ hexp_tree e d od dbg;;
+ DO nd <~ hdeps_set d x ht;;
+ hinst_deps i' nd od
+ end.
-Lemma hinst_deps_correct i: forall d1 od1,
- WHEN hinst_deps i d1 od1 ~> d1' THEN
- forall od2 d2, (forall x, pdeps_get od1 x = deps_get od2 x) ->
- (forall x, pdeps_get d1 x = deps_get d2 x) ->
- forall x, pdeps_get d1' x = deps_get (inst_deps i d2 od2) x.
+Lemma hinst_deps_correct i: forall hd hod,
+ WHEN hinst_deps i hd hod ~> hd' THEN
+ forall ge od d, deps_model ge od hod -> deps_model ge d hd -> deps_model ge (inst_deps i d od) hd'.
Proof.
induction i; simpl; wlp_simplify.
- + cutrewrite (failsafe (deps_get d2 a0) = failsafe (data exta0)).
- - erewrite H0, H2; simpl; eauto. clear exta2 Hexta2 H2; auto.
- intros x0; destruct (R.eq_dec a0 x0).
- * subst. autorewrite with dict_rw. rewrite set_spec_eq. erewrite H1; eauto.
- * rewrite set_spec_diff, pset_spec_diff; auto.
- - rewrite H, H4; auto.
- + cutrewrite (failsafe (deps_get d2 a0) = failsafe (data exta0)).
- - erewrite H0, H3; simpl; eauto. clear exta3 Hexta3 H3; auto.
- intros x0; destruct (R.eq_dec a0 x0).
- * subst; autorewrite with dict_rw. rewrite H2.
- erewrite H, H1; eauto. rewrite set_spec_eq. congruence.
- * rewrite set_spec_diff, pset_spec_diff; auto.
- - rewrite H, H5; auto.
Qed.
Global Opaque hinst_deps.
-Hint Resolve hinst_deps_correct: wlp.
+Local Hint Resolve hinst_deps_correct: wlp.
(* logging info: we log the number of inst-instructions passed ! *)
Variable log: unit -> ?? unit.
@@ -280,24 +282,24 @@ Fixpoint hbblock_deps_rec (p: bblock) (d: hdeps): ?? hdeps :=
hbblock_deps_rec p' d'
end.
-Lemma hbblock_deps_rec_correct p: forall d1,
- WHEN hbblock_deps_rec p d1 ~> d1' THEN
- forall d2, (forall x, pdeps_get d1 x = deps_get d2 x) -> forall x, pdeps_get d1' x = deps_get (bblock_deps_rec p d2) x.
+Lemma hbblock_deps_rec_correct p: forall hd,
+ WHEN hbblock_deps_rec p hd ~> hd' THEN forall ge d, deps_model ge d hd -> deps_model ge (bblock_deps_rec p d) hd'.
Proof.
induction p; simpl; wlp_simplify.
Qed.
Global Opaque hbblock_deps_rec.
-Hint Resolve hbblock_deps_rec_correct: wlp.
+Local Hint Resolve hbblock_deps_rec_correct: wlp.
Definition hbblock_deps: bblock -> ?? hdeps
- := fun p => hbblock_deps_rec p Dict.empty.
+ := fun p => hbblock_deps_rec p {| hpre:= nil ; hpost := Dict.empty |}.
Lemma hbblock_deps_correct p:
- WHEN hbblock_deps p ~> d1 THEN forall x, pdeps_get d1 x = deps_get (bblock_deps p) x.
+ WHEN hbblock_deps p ~> hd THEN forall ge, deps_model ge (bblock_deps p) hd.
Proof.
- unfold bblock_deps; wlp_simplify. erewrite H; eauto.
- intros; autorewrite with dict_rw; auto. rewrite empty_spec. reflexivity.
+ unfold bblock_deps; wlp_simplify. eapply H. clear H.
+ unfold deps_model, pdeps_get, hdeps_valid, deps_eval, deps_get; simpl.
+ intuition; rewrite !Dict.empty_spec; simpl; auto.
Qed.
Global Opaque hbblock_deps.
@@ -324,11 +326,6 @@ Definition tree_hash_eq (ta tb: tree): ?? bool :=
DO b <~ op_eq oa ob ;;
if b then phys_eq lta ltb
else RET false
- | Terase t1a t2a, Terase t1b t2b =>
- DO b <~ phys_eq t1a t1b ;;
- if b
- then phys_eq t2a t2b
- else RET false
| _,_ => RET false
end.
@@ -358,7 +355,7 @@ Qed.
Global Opaque list_tree_hash_eq.
Hint Resolve list_tree_hash_eq_correct: wlp.
-Lemma pdeps_get_intro d1 d2:
+Lemma pdeps_get_intro (d1 d2: hdeps):
(forall x, Dict.get d1 x = Dict.get d2 x) -> (forall x, pdeps_get d1 x = pdeps_get d2 x).
Proof.
unfold pdeps_get; intros H x; rewrite H. destruct (Dict.get d2 x); auto.
@@ -366,6 +363,19 @@ Qed.
Local Hint Resolve hbblock_deps_correct Dict.eq_test_correct: wlp.
+(* TODO:
+ A REVOIR pour que Dict.test_eq qui soit insensible aux infos de debug !
+ (cf. definition ci-dessous).
+ Il faut pour généraliser hash_params sur des Setoid (et les Dict aussi, avec ListSetoid, etc)...
+ *)
+Program Definition mk_hash_params (log: hashV tree -> ?? unit): Dict.hash_params (hashV tree) :=
+ {| (* Dict.test_eq := fun (ht1 ht2: hashV tree) => phys_eq (data ht1) (data ht2); *)
+ Dict.test_eq := phys_eq;
+ Dict.hashing := fun (ht: hashV tree) => RET (hid ht);
+ Dict.log := log |}.
+Obligation 1.
+ eauto with wlp.
+Qed.
(*** A GENERIC EQ_TEST: IN ORDER TO SUPPORT SEVERAL DEBUGGING MODE !!! ***)
@@ -376,7 +386,6 @@ Variable dbg2: R.t -> ?? option pstring. (* log of p2 insts *)
Variable log1: unit -> ?? unit. (* log of p1 insts *)
Variable log2: unit -> ?? unit. (* log of p2 insts *)
-
Variable hco_tree: hashConsing tree.
Hypothesis hco_tree_correct: hCons_spec hco_tree.
Variable hco_list: hashConsing list_tree.
@@ -385,34 +394,48 @@ Hypothesis hco_list_correct: hCons_spec hco_list.
Variable print_error_end: hdeps -> hdeps -> ?? unit.
Variable print_error: pstring -> ?? unit.
+Variable check_failpreserv: bool.
+Variable dbg_failpreserv: hashV tree -> ?? unit. (* info of additional failure of the output bbloc p2 wrt the input bbloc p1 *)
+
Program Definition g_bblock_simu_test (p1 p2: bblock): ?? bool :=
+ DO failure_in_failpreserv <~ make_cref false;;
DO r <~ (TRY
DO d1 <~ hbblock_deps (hC hco_tree) (hC hco_list) dbg1 log1 p1 ;;
DO d2 <~ hbblock_deps (hC_known hco_tree) (hC_known hco_list) dbg2 log2 p2 ;;
DO b <~ Dict.eq_test d1 d2 ;;
- if b then RET true
- else (
+ if b then (
+ if check_failpreserv then (
+ let hp := mk_hash_params dbg_failpreserv in
+ failure_in_failpreserv.(set)(true);;
+ Sets.assert_list_incl hp d2.(hpre) d1.(hpre);;
+ RET true
+ ) else RET false
+ ) else (
print_error_end d1 d2 ;;
RET false
)
CATCH_FAIL s, _ =>
- print_error s;;
- RET false
+ DO b <~ failure_in_failpreserv.(get)();;
+ if b then RET false
+ else print_error s;; RET false
ENSURE (fun b => b=true -> forall ge, bblock_simu ge p1 p2));;
RET (`r).
Obligation 1.
- destruct hco_tree_correct as [X1 X2], hco_list_correct as [Y1 Y2].
+ destruct hco_tree_correct as [TEQ1 TEQ2], hco_list_correct as [LEQ1 LEQ2].
constructor 1; wlp_simplify; try congruence.
+ destruct (H ge) as (EQPRE1&EQPOST1); destruct (H0 ge) as (EQPRE2&EQPOST2); clear H H0.
apply bblock_deps_simu; auto.
- intros; rewrite <- H, <- H0.
- apply pdeps_get_intro. auto.
+ + intros m; rewrite <- EQPRE1, <- EQPRE2.
+ unfold incl, hdeps_valid in * |- *; intuition eauto.
+ + intros m0 x m1 VALID; rewrite <- EQPOST1, <- EQPOST2.
+ erewrite pdeps_get_intro; auto. auto.
Qed.
Theorem g_bblock_simu_test_correct p1 p2:
WHEN g_bblock_simu_test p1 p2 ~> b THEN b=true -> forall ge, bblock_simu ge p1 p2.
Proof.
wlp_simplify.
- destruct exta; simpl in * |- *; auto.
+ destruct exta0; simpl in * |- *; auto.
Qed.
Global Opaque g_bblock_simu_test.
@@ -429,6 +452,7 @@ Definition msg_error_on_end: pstring := "mismatch in final assignments !".
Definition msg_unknow_tree: pstring := "unknown tree node".
Definition msg_unknow_list_tree: pstring := "unknown list node".
Definition msg_number: pstring := "on 2nd bblock -- on inst num ".
+Definition msg_notfailpreserv: pstring := "a possible failure of 2nd bblock is absent in 1st bblock".
Definition print_error_end (_ _: hdeps): ?? unit
:= println (msg_prefix +; msg_error_on_end).
@@ -437,17 +461,30 @@ Definition print_error (log: logger unit) (s:pstring): ?? unit
:= DO n <~ log_info log ();;
println (msg_prefix +; msg_number +; n +; " -- " +; s).
+Definition failpreserv_error (_: hashV tree): ?? unit
+ := println (msg_prefix +; msg_notfailpreserv).
Program Definition bblock_simu_test (p1 p2: bblock): ?? bool :=
DO log <~ count_logger ();;
DO hco_tree <~ mk_annot (hCons tree_hash_eq (fun _ => RET msg_unknow_tree));;
DO hco_list <~ mk_annot (hCons list_tree_hash_eq (fun _ => RET msg_unknow_list_tree));;
- g_bblock_simu_test no_dbg no_dbg skip (log_insert log) hco_tree _ hco_list _ print_error_end (print_error log) p1 p2.
-Obligation 1.
+ g_bblock_simu_test
+ no_dbg
+ no_dbg
+ skip
+ (log_insert log)
+ hco_tree _
+ hco_list _
+ print_error_end
+ (print_error log)
+ true (* check_failpreserv *)
+ failpreserv_error
+ p1 p2.
+Obligation 1.
generalize (hCons_correct _ _ _ _ H0); clear H0.
constructor 1; wlp_simplify.
Qed.
-Obligation 2.
+Obligation 2.
generalize (hCons_correct _ _ _ _ H); clear H.
constructor 1; wlp_simplify.
Qed.
@@ -486,10 +523,6 @@ Definition print_raw_htree (td: pre_hashV tree): ?? unit :=
DO so <~ string_of_op o;;
DO sl <~ string_of_hashcode lid;;
println (so +; " " +; (list_id sl))
- | (Terase _ _), [ _ ; t1; t2 ] =>
- DO st1 <~ string_of_hashcode t1 ;;
- DO st2 <~ string_of_hashcode t2 ;;
- println((tree_id st1) +; " erases " +; (tree_id st2))
| _, _ => FAILWITH "unexpected hcodes"
end.
@@ -521,9 +554,6 @@ Fixpoint string_of_tree (t: tree) (pt: pre_hashV tree) : ?? pstring :=
DO pl <~ get_hlist lid;;
DO sl <~ string_of_list_tree l pl;;
RET (so +; "(" +; sl +; ")")
- | Terase t _, [ _ ; tid; _ ] =>
- DO pt <~ get_htree tid ;;
- string_of_tree t pt
| _, _ => FAILWITH "unexpected hcodes"
end
end
@@ -699,11 +729,13 @@ Program Definition verb_bblock_simu_test (p1 p2: bblock): ?? bool :=
(log_debug log1)
simple_debug
(hlog log1 hco_tree hco_list)
- (log_insert log2)
- hco_tree _
- hco_list _
+ (log_insert log2)
+ hco_tree _
+ hco_list _
(print_error_end1 hco_tree hco_list)
- (print_error1 hco_tree hco_list cr log2)
+ (print_error1 hco_tree hco_list cr log2)
+ true
+ failpreserv_error (* TODO: debug info *)
p1 p2;;
if result1
then RET true
@@ -718,10 +750,12 @@ Program Definition verb_bblock_simu_test (p1 p2: bblock): ?? bool :=
simple_debug
(hlog log1 hco_tree hco_list)
(log_insert log2)
- hco_tree _
- hco_list _
+ hco_tree _
+ hco_list _
(print_error_end2 hco_tree hco_list)
- (print_error2 hco_tree hco_list cr log2)
+ (print_error2 hco_tree hco_list cr log2)
+ false
+ (fun _ => RET tt)
p2 p1;;
if result2
then (
@@ -796,7 +830,7 @@ Proof.
Qed.
Global Opaque eq_test.
-(* get some key of a non-empty d *)
+(* ONLY FOR DEBUGGING INFO: get some key of a non-empty d *)
Fixpoint pick {A} (d: t A): ?? R.t :=
match d with
| Leaf _ => FAILWITH "unexpected empty dictionary"
@@ -809,7 +843,7 @@ Fixpoint pick {A} (d: t A): ?? R.t :=
RET (xO p)
end.
-
+(* ONLY FOR DEBUGGING INFO: find one variable on which d1 and d2 differs *)
Fixpoint not_eq_witness {A} (d1 d2: t A): ?? option R.t :=
match d1, d2 with
| Leaf _, Leaf _ => RET None