aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYann Herklotz <git@yannherklotz.com>2022-07-19 08:53:57 +0200
committerYann Herklotz <git@yannherklotz.com>2022-07-19 08:53:57 +0200
commit5321f82fb46a87ca372b10ba5729509871cc935a (patch)
tree599ab805c9a807e9883cbae2dac034162e95890f
parentaa753acd776638971abb5d9901cc99ef259cb314 (diff)
downloadvericert-5321f82fb46a87ca372b10ba5729509871cc935a.tar.gz
vericert-5321f82fb46a87ca372b10ba5729509871cc935a.zip
Work on implementing abstract predicates
-rw-r--r--benchmarks/polybench-syn/common.mk8
-rw-r--r--src/common/Monad.v11
-rw-r--r--src/common/Vericertlib.v40
-rw-r--r--src/hls/Abstr.v202
-rw-r--r--src/hls/Gible.v2
-rw-r--r--src/hls/GiblePargen.v200
-rw-r--r--src/hls/GiblePargenproof.v20
-rw-r--r--src/hls/HTLPargen.v1
-rw-r--r--src/hls/HTLgen.v1
-rw-r--r--src/hls/HashTree.v26
-rw-r--r--src/hls/PipelineOp.v4
-rw-r--r--src/hls/Predicate.v333
-rw-r--r--src/hls/PrintAbstr.ml30
-rw-r--r--src/hls/PrintGible.ml34
-rw-r--r--src/hls/RTLParFU.v2
-rw-r--r--test/Makefile2
16 files changed, 528 insertions, 388 deletions
diff --git a/benchmarks/polybench-syn/common.mk b/benchmarks/polybench-syn/common.mk
index e155e4a..877dd68 100644
--- a/benchmarks/polybench-syn/common.mk
+++ b/benchmarks/polybench-syn/common.mk
@@ -1,5 +1,5 @@
VERICERT ?= vericert
-VERICERT_OPTS ?= -DSYNTHESIS -fschedule -fif-conv
+VERICERT_OPTS ?= -DSYNTHESIS -fschedule -fif-conv -dgblseq -dgblpar
IVERILOG ?= iverilog
IVERILOG_OPTS ?=
@@ -9,17 +9,17 @@ VERILATOR_OPTS ?= -Wno-fatal -Wno-lint -Wno-style -Wno-WIDTH --top main --exe $(
TARGETS ?=
-%.v: %.c
+%.sv: %.c
@echo -e "\033[0;35mMAKE\033[0m" $<
$(VERICERT) $(VERICERT_OPTS) $< -o $@
-%.iver: %.v
+%.iver: %.sv
$(IVERILOG) -o $@ $(IVERILOG_OPTS) $<
%.gcc: %.c
$(CC) $(CFLAGS) $< -o $@
-%.verilator: %.v
+%.verilator: %.sv
$(VERILATOR) $(VERILATOR_OPTS) --Mdir $@ --cc $<
@echo -e $(MAKE) -C $@ -f Vmain.mk
@$(MAKE) -C $@ -f Vmain.mk &>/dev/null
diff --git a/src/common/Monad.v b/src/common/Monad.v
index fcbe527..ece047c 100644
--- a/src/common/Monad.v
+++ b/src/common/Monad.v
@@ -18,6 +18,8 @@
From Coq Require Import Lists.List.
+Declare Scope monad_scope.
+
Module Type Monad.
Parameter mon : Type -> Type.
@@ -36,17 +38,18 @@ End Monad.
Module MonadExtra(M : Monad).
Import M.
- Module MonadNotation.
+ Module Import MonadNotation.
Notation "'do' X <- A ; B" :=
(bind A (fun X => B))
- (at level 200, X name, A at level 100, B at level 200).
+ (at level 200, X name, A at level 100, B at level 200) : monad_scope.
Notation "'do' ( X , Y ) <- A ; B" :=
(bind2 A (fun X Y => B))
- (at level 200, X name, Y name, A at level 100, B at level 200).
+ (at level 200, X name, Y name, A at level 100, B at level 200) : monad_scope.
End MonadNotation.
- Import MonadNotation.
+
+ #[local] Open Scope monad_scope.
Fixpoint traverselist {A B: Type} (f: A -> mon B) (l: list A) {struct l}: mon (list B) :=
match l with
diff --git a/src/common/Vericertlib.v b/src/common/Vericertlib.v
index 5540f34..24abece 100644
--- a/src/common/Vericertlib.v
+++ b/src/common/Vericertlib.v
@@ -31,6 +31,7 @@ Require Import compcert.lib.Integers.
Require Import compcert.lib.Maps.
Require Import vericert.common.Show.
+Require Export vericert.common.Optionmonad.
(* Depend on CompCert for the basic library, as they declare and prove some
useful theorems. *)
@@ -198,45 +199,6 @@ Ltac crush := simplify; try discriminate; try congruence; try lia; liapp;
Definition compose (A B C : Type) (f : B -> C) (g : A -> B) (x : A) : C := f (g x). *)
-Module Option.
-
-Definition default {T : Type} (x : T) (u : option T) : T :=
- match u with
- | Some y => y
- | _ => x
- end.
-
-Definition map {S : Type} {T : Type} (f : S -> T) (u : option S) : option T :=
- match u with
- | Some y => Some (f y)
- | _ => None
- end.
-
-Definition liftA2 {T : Type} (f : T -> T -> T) (a : option T) (b : option T) : option T :=
- match a with
- | Some x => map (f x) b
- | _ => None
- end.
-
-Definition bind {A B : Type} (f : option A) (g : A -> option B) : option B :=
- match f with
- | Some a => g a
- | _ => None
- end.
-
-Definition join {A : Type} (a : option (option A)) : option A :=
- match a with
- | None => None
- | Some a' => a'
- end.
-
-Module Notation.
-Notation "'do' X <- A ; B" := (bind A (fun X => B))
- (at level 200, X name, A at level 100, B at level 200).
-End Notation.
-
-End Option.
-
Parameter debug_print : string -> unit.
Definition debug_show {A B : Type} `{Show A} (a : A) (b : B) : B :=
diff --git a/src/hls/Abstr.v b/src/hls/Abstr.v
index 9902dc9..bfe49f3 100644
--- a/src/hls/Abstr.v
+++ b/src/hls/Abstr.v
@@ -91,6 +91,8 @@ Module R_indexed.
Definition eq := resource_eq.
End R_indexed.
+Compute xO xH.
+
(*|
We can then create expressions that mimic the expressions defined in RTLBlock
and RTLPar, which use expressions instead of registers as their inputs and
@@ -116,17 +118,12 @@ Inductive expression : Type :=
| Eexit : cf_instr -> expression
with expression_list : Type :=
| Enil : expression_list
-| Econs : expression -> expression_list -> expression_list
-.
+| Econs : expression -> expression_list -> expression_list.
Definition apred : Type := expression.
-
-Inductive apred_op : Type :=
-| APlit: (bool * apred) -> apred_op
-| APtrue: apred_op
-| APfalse: apred_op
-| APand: apred_op -> apred_op -> apred_op
-| APor: apred_op -> apred_op -> apred_op.
+Definition apred_op := @Predicate.pred_op apred.
+Definition pred_op := @Predicate.pred_op positive.
+Definition predicate := positive.
(* Declare Scope apred_op. *)
@@ -222,6 +219,16 @@ Proof.
right. unfold not in *; intros. apply H0. inv H1. now inv H3. }
Qed.
+Fixpoint filter {A: Type} (f: A -> bool) (l: non_empty A) : option (non_empty A) :=
+ match l with
+ | singleton a =>
+ if f a then Some (singleton a) else None
+ | a ::| b =>
+ if f a then
+ match filter f b with Some x => Some (a ::| x) | None => Some (singleton a) end
+ else filter f b
+ end.
+
End NonEmpty.
Module NE := NonEmpty.
@@ -233,6 +240,7 @@ Definition apredicated A := NE.non_empty (apred_op * A).
Definition predicated A := NE.non_empty (pred_op * A).
Definition apred_expr := apredicated expression.
+Definition pred_expr := predicated expression.
(*|
Using ``IMap`` we can create a map from resources to any other type, as
@@ -245,7 +253,7 @@ Definition forest : Type := Rtree.t apred_expr.
Definition get_forest v (f: forest) :=
match Rtree.get v f with
- | None => NE.singleton (APtrue, (Ebase v))
+ | None => NE.singleton (Ptrue, (Ebase v))
| Some v' => v'
end.
@@ -345,19 +353,19 @@ with sem_val_list : ctx -> expression_list -> list val -> Prop :=
.
Inductive eval_apred (c: ctx): apred_op -> bool -> Prop :=
-| eval_APtrue : eval_apred c APtrue true
-| eval_APfalse : eval_apred c APfalse false
+| eval_APtrue : eval_apred c Ptrue true
+| eval_APfalse : eval_apred c Pfalse false
| eval_APlit : forall p (b: bool) bres,
sem_pred c p (if b then bres else negb bres) ->
- eval_apred c (APlit (b, p)) bres
+ eval_apred c (Plit (b, p)) bres
| eval_APand : forall p1 p2 b1 b2,
eval_apred c p1 b1 ->
eval_apred c p2 b2 ->
- eval_apred c (APand p1 p2) (b1 && b2)
+ eval_apred c (Pand p1 p2) (b1 && b2)
| eval_APor1 : forall p1 p2 b1 b2,
eval_apred c p1 b1 ->
eval_apred c p2 b2 ->
- eval_apred c (APor p1 p2) (b1 || b2).
+ eval_apred c (Por p1 p2) (b1 || b2).
Inductive sem_pred_expr {B: Type} (sem: ctx -> expression -> B -> Prop):
ctx -> apred_expr -> B -> Prop :=
@@ -527,22 +535,22 @@ Import HT.
Fixpoint hash_predicate (max: predicate) (ap: apred_op) (h: hash_tree)
: pred_op * hash_tree :=
match ap with
- | APtrue => (Ptrue, h)
- | APfalse => (Pfalse, h)
- | APlit (b, ap') =>
+ | Ptrue => (Ptrue, h)
+ | Pfalse => (Pfalse, h)
+ | Plit (b, ap') =>
let (p', h') := hash_value max ap' h in
(Plit (b, p'), h')
- | APand p1 p2 =>
+ | Pand p1 p2 =>
let (p1', h') := hash_predicate max p1 h in
let (p2', h'') := hash_predicate max p2 h' in
(Pand p1' p2', h'')
- | APor p1 p2 =>
+ | Por p1 p2 =>
let (p1', h') := hash_predicate max p1 h in
let (p2', h'') := hash_predicate max p2 h' in
(Por p1' p2', h'')
end.
-Fixpoint norm_expression (max: predicate) (pe: apred_expr) (h: hash_tree)
+Fixpoint anorm_expression (max: predicate) (pe: apred_expr) (h: hash_tree)
: (PTree.t pred_op) * hash_tree :=
match pe with
| NE.singleton (p, e) =>
@@ -551,7 +559,7 @@ Fixpoint norm_expression (max: predicate) (pe: apred_expr) (h: hash_tree)
(PTree.set hashed_e hashed_p (PTree.empty _), h'')
| (p, e) ::| pr =>
let (hashed_e, h') := hash_value max e h in
- let (norm_pr, h'') := norm_expression max pr h' in
+ let (norm_pr, h'') := anorm_expression max pr h' in
let (hashed_p, h''') := hash_predicate max p h'' in
match norm_pr ! hashed_e with
| Some pr_op =>
@@ -561,7 +569,24 @@ Fixpoint norm_expression (max: predicate) (pe: apred_expr) (h: hash_tree)
end
end.
-Definition mk_pred_stmnt' e p_e := ¬ p_e ∨ Plit (true, e).
+Fixpoint norm_expression (max: predicate) (pe: pred_expr) (h: hash_tree)
+ : (PTree.t pred_op) * hash_tree :=
+ match pe with
+ | NE.singleton (p, e) =>
+ let (hashed_e, h') := hash_value max e h in
+ (PTree.set hashed_e p (PTree.empty _), h')
+ | (p, e) ::| pr =>
+ let (hashed_e, h') := hash_value max e h in
+ let (norm_pr, h'') := norm_expression max pr h' in
+ match norm_pr ! hashed_e with
+ | Some pr_op =>
+ (PTree.set hashed_e (pr_op ∨ p) norm_pr, h'')
+ | None =>
+ (PTree.set hashed_e p norm_pr, h'')
+ end
+ end.
+
+Definition mk_pred_stmnt' (e: predicate) p_e := ¬ p_e ∨ Plit (true, e).
Definition mk_pred_stmnt t := PTree.fold (fun x a b => mk_pred_stmnt' a b ∧ x) t T.
@@ -571,6 +596,10 @@ Definition encode_expression max pe h :=
let (tree, h) := norm_expression max pe h in
(mk_pred_stmnt tree, h).
+Definition aencode_expression max pe h :=
+ let (tree, h) := anorm_expression max pe h in
+ (mk_pred_stmnt tree, h).
+
(*Fixpoint encode_expression_ne (max: predicate) (pe: pred_expr_ne) (h: hash_tree)
: (PTree.t pred_op) * hash_tree :=
match pe with
@@ -583,11 +612,11 @@ Definition encode_expression max pe h :=
(Pand (Por (Pnot p) (Pvar p')) p'', h'')
end.*)
-(* Fixpoint max_pred_expr (pe: pred_expr) : positive := *)
-(* match pe with *)
-(* | NE.singleton (p, e) => max_predicate p *)
-(* | (p, e) ::| pe' => Pos.max (max_predicate p) (max_pred_expr pe') *)
-(* end. *)
+Fixpoint max_pred_expr (pe: pred_expr) : positive :=
+ match pe with
+ | NE.singleton (p, e) => max_predicate p
+ | (p, e) ::| pe' => Pos.max (max_predicate p) (max_pred_expr pe')
+ end.
Definition empty : forest := Rtree.empty _.
@@ -634,29 +663,9 @@ Inductive similar {A B} : @ctx A -> @ctx B -> Prop :=
similar (mk_ctx ist sp ge) (mk_ctx ist' sp tge).
Definition beq_pred_expr_once (pe1 pe2: apred_expr) : bool :=
- match pe1, pe2 with
- (* PEsingleton None e1, PEsingleton None e2 => beq_expression e1 e2
- | PEsingleton (Some p1) e1, PEsingleton (Some p2) e2 =>
- if beq_expression e1 e2
- then match sat_pred_simple bound (Por (Pand p1 (Pnot p2)) (Pand p2 (Pnot p1))) with
- | Some None => true
- | _ => false
- end
- else false
- | PEsingleton (Some p) e1, PEsingleton None e2
- | PEsingleton None e1, PEsingleton (Some p) e2 =>
- if beq_expression e1 e2
- then match sat_pred_simple bound (Pnot p) with
- | Some None => true
- | _ => false
- end
- else false*)
- | pe1, pe2 =>
- (* let max := Pos.max (max_pred_expr pe1) (max_pred_expr pe2) in *)
- let (p1, h) := encode_expression 1%positive pe1 (PTree.empty _) in
- let (p2, h') := encode_expression 1%positive pe2 h in
- equiv_check p1 p2
- end.
+ let (p1, h) := aencode_expression 1%positive pe1 (PTree.empty _) in
+ let (p2, h') := aencode_expression 1%positive pe2 h in
+ equiv_check p1 p2.
Definition tree_equiv_check_el (np2: PTree.t pred_op) (n: positive) (p: pred_op): bool :=
match np2 ! n with
@@ -725,43 +734,39 @@ Module Type AbstrPredSet.
End AbstrPredSet.
-Section ABSTR_PRED.
-
- Context (h: hash_tree).
- Context (m: predicate).
-
- Definition sat_aequiv ap1 ap2 :=
- exists p1 p2,
- sat_equiv p1 p2
- /\ hash_predicate m ap1 h = (p1, h)
- /\ hash_predicate m ap2 h = (p2, h).
-
- Lemma aequiv_symm : forall a b, sat_aequiv a b -> sat_aequiv b a.
- Proof.
- unfold sat_aequiv; simplify; do 2 eexists; simplify; [symmetry | |]; eauto.
- Qed.
-
- Lemma aequiv_trans :
- forall a b c,
- sat_aequiv a b ->
- sat_aequiv b c ->
- sat_aequiv a c.
- Proof.
- unfold sat_aequiv; intros * H H0; simplify; do 2 eexists; simplify;
- [| eassumption | eassumption]; rewrite H0 in H3; inv H3.
- transitivity x2; auto.
- Qed.
+Definition sat_aequiv ap1 ap2 :=
+ exists h p1 p2,
+ sat_equiv p1 p2
+ /\ hash_predicate 1 ap1 h = (p1, h)
+ /\ hash_predicate 1 ap2 h = (p2, h).
- Instance PER_aequiv : PER sat_aequiv :=
- { PER_Symmetric := aequiv_symm;
- PER_Transitive := aequiv_trans;
- }.
-
-End ABSTR_PRED.
+Lemma aequiv_symm : forall a b, sat_aequiv a b -> sat_aequiv b a.
+Proof.
+ unfold sat_aequiv; simplify; do 3 eexists; simplify; [symmetry | |]; eauto.
+Qed.
+Lemma existsh :
+ forall ap1,
+ exists h p1,
+ hash_predicate 1 ap1 h = (p1, h).
+Proof. Admitted.
+Lemma aequiv_refl : forall a, sat_aequiv a a.
+Proof.
+ unfold sat_aequiv; intros.
+ pose proof (existsh a); simplify.
+ do 3 eexists; simplify; eauto. reflexivity.
+Qed.
-Definition hash_predicate
+Lemma aequiv_trans :
+ forall a b c,
+ sat_aequiv a b ->
+ sat_aequiv b c ->
+ sat_aequiv a c.
+Proof.
+ unfold sat_aequiv; intros.
+ simplify.
+Abort.
Lemma norm_expr_mutexcl :
forall m pe h t h' e e' p p',
@@ -773,7 +778,7 @@ Lemma norm_expr_mutexcl :
p ⇒ ¬ p'.
Proof. Abort.
-Lemma norm_expression_sem_pred :
+(*Lemma norm_expression_sem_pred :
forall A B sem ctx pe v,
sem_pred_expr sem ctx pe v ->
forall pt et et' max,
@@ -827,12 +832,11 @@ Lemma norm_expression_sem_pred2 :
predicated_mutexcl pe ->
norm_expression (max_pred_expr pe) pe et = (pt, et') ->
sem_pred_expr sem ctx pe v.
-Proof. Admitted.
+Proof. Admitted.*)
-Definition beq_pred_expr (pe1 pe2: pred_expr) : bool :=
- let max := Pos.max (max_pred_expr pe1) (max_pred_expr pe2) in
- let (np1, h) := norm_expression max pe1 (PTree.empty _) in
- let (np2, h') := norm_expression max pe2 h in
+Definition beq_pred_expr (pe1 pe2: apred_expr) : bool :=
+ let (np1, h) := anorm_expression 1 pe1 (PTree.empty _) in
+ let (np2, h') := anorm_expression 1 pe2 h in
forall_ptree (tree_equiv_check_el np2) np1
&& forall_ptree (tree_equiv_check_None_el np1) np2.
@@ -1102,7 +1106,7 @@ Section CORRECT.
Proof.
Abort.*)
- Lemma norm_expr_implies :
+(* Lemma norm_expr_implies :
forall x m h t h' e expr p,
norm_expression m x h = (t, h') ->
h' ! e = Some expr ->
@@ -1140,7 +1144,7 @@ Section CORRECT.
pose proof H0; rewrite e0 in H2;
apply sem_pred_expr_cons_false; auto; inv H; crush.
- inv H; constructor; auto; now apply sem_pred_expr_cons_false.
- Qed.
+ Qed.*)
Section SEM_PRED.
@@ -1153,7 +1157,7 @@ Section CORRECT.
repeat (nicify_hypotheses; nicify_goals; kill_bools; substpp);
cbn -[l] in *.
- Lemma check_correct_sem_value:
+(* Lemma check_correct_sem_value:
forall x x' v v' t t' h h',
beq_pred_expr x x' = true ->
predicated_mutexcl x -> predicated_mutexcl x' ->
@@ -1270,7 +1274,7 @@ Section CORRECT.
eapply exists_norm_expr2 in DSTR; try solve [eapply norm_expr_constant; eassumption | eassumption].
}
}
- Admitted.*) Abort.
+ Admitted.*) Abort.*)
End SEM_PRED.
@@ -1281,7 +1285,7 @@ Section CORRECT.
Context (osem: @ctx tfd -> expression -> B -> Prop).
Context (SEMCORR: forall e v, isem ictx e v -> osem octx e v).
- Lemma sem_pred_tree_corr:
+(* Lemma sem_pred_tree_corr:
forall x x' v t t' h h',
beq_pred_expr x x' = true ->
predicated_mutexcl x -> predicated_mutexcl x' ->
@@ -1289,7 +1293,7 @@ Section CORRECT.
norm_expression (Pos.max (max_pred_expr x) (max_pred_expr x')) x' h = (t', h') ->
sem_pred_tree isem ictx h t v ->
sem_pred_tree osem octx h' t' v.
- Proof using SEMCORR. Admitted.
+ Proof using SEMCORR. Admitted.*)
End SEM_PRED_CORR.
@@ -1325,7 +1329,7 @@ Admitted.
End CORRECT.
Lemma get_empty:
- forall r, empty#r = NE.singleton (T, Ebase r).
+ forall r, empty#r = NE.singleton (Ptrue, Ebase r).
Proof.
intros; unfold get_forest;
destruct_match; auto; [ ];
@@ -1420,7 +1424,7 @@ End BOOLEAN_EQUALITY.
Lemma map1:
forall w dst dst',
dst <> dst' ->
- (empty # dst <- w) # dst' = NE.singleton (T, Ebase dst').
+ (empty # dst <- w) # dst' = NE.singleton (Ptrue, Ebase dst').
Proof. intros; unfold get_forest; rewrite Rtree.gso; auto; apply get_empty. Qed.
Lemma genmap1:
@@ -1430,7 +1434,7 @@ Lemma genmap1:
Proof. intros; unfold get_forest; rewrite Rtree.gso; auto. Qed.
Lemma map2:
- forall (v : pred_expr) x rs,
+ forall (v : apred_expr) x rs,
(rs # x <- v) # x = v.
Proof. intros; unfold get_forest; rewrite Rtree.gss; trivial. Qed.
diff --git a/src/hls/Gible.v b/src/hls/Gible.v
index fdc9a9d..0603269 100644
--- a/src/hls/Gible.v
+++ b/src/hls/Gible.v
@@ -43,6 +43,8 @@ Require Import Predicate.
Require Import Vericertlib.
Definition node := positive.
+Definition predicate := positive.
+Definition pred_op := @pred_op predicate.
(*|
.. index::
diff --git a/src/hls/GiblePargen.v b/src/hls/GiblePargen.v
index 01ee2cd..dae1efc 100644
--- a/src/hls/GiblePargen.v
+++ b/src/hls/GiblePargen.v
@@ -27,6 +27,7 @@ Require Import compcert.lib.Maps.
Require compcert.verilog.Op.
Require Import vericert.common.Vericertlib.
+Require Import vericert.common.Monad.
Require Import vericert.hls.GibleSeq.
Require Import vericert.hls.GiblePar.
Require Import vericert.hls.Gible.
@@ -39,6 +40,11 @@ Import NE.NonEmptyNotation.
#[local] Open Scope forest.
#[local] Open Scope pred_op.
+Module OptionExtra := MonadExtra(Option).
+Import OptionExtra.
+Import OptionExtra.MonadNotation.
+#[local] Open Scope monad_scope.
+
(*|
====================
Gible Par Generation
@@ -53,7 +59,7 @@ to correctly translate the predicates.
|*)
Fixpoint list_translation (l : list reg) (f : forest) {struct l}
- : list pred_expr :=
+ : list apred_expr :=
match l with
| nil => nil
| i :: l => (f # (Reg i)) :: (list_translation l f)
@@ -65,58 +71,58 @@ Fixpoint replicate {A} (n: nat) (l: A) :=
| S n => l :: replicate n l
end.
-Definition merge''' x y :=
+Definition merge''' {A: Type} (x y: option (@Predicate.pred_op A)) :=
match x, y with
| Some p1, Some p2 => Some (Pand p1 p2)
| Some p, None | None, Some p => Some p
| None, None => None
end.
-Definition merge'' x :=
+Definition merge'' {A: Type} x :=
match x with
- | ((a, e), (b, el)) => (merge''' a b, Econs e el)
+ | ((a, e), (b, el)) => (@merge''' A a b, Econs e el)
end.
-Definition map_pred_op {A B} (pf: option pred_op * (A -> B))
- (pa: option pred_op * A): option pred_op * B :=
+Definition map_pred_op {A B P: Type} (pf: option (@Predicate.pred_op P) * (A -> B))
+ (pa: option (@Predicate.pred_op P) * A): option (@Predicate.pred_op P) * B :=
match pa, pf with
| (p, a), (p', f) => (merge''' p p', f a)
end.
-Definition predicated_prod {A B: Type} (p1: predicated A) (p2: predicated B) :=
+Definition predicated_prod {A B: Type} (p1: apredicated A) (p2: apredicated B) :=
NE.map (fun x => match x with ((a, b), (c, d)) => (Pand a c, (b, d)) end)
(NE.non_empty_prod p1 p2).
-Definition predicated_map {A B: Type} (f: A -> B) (p: predicated A)
- : predicated B := NE.map (fun x => (fst x, f (snd x))) p.
+Definition predicated_map {A B: Type} (f: A -> B) (p: apredicated A)
+ : apredicated B := NE.map (fun x => (fst x, f (snd x))) p.
(*map (fun x => (fst x, Econs (snd x) Enil)) pel*)
-Definition merge' (pel: pred_expr) (tpel: predicated expression_list) :=
+Definition merge' (pel: apred_expr) (tpel: apredicated expression_list) :=
predicated_map (uncurry Econs) (predicated_prod pel tpel).
-Fixpoint merge (pel: list pred_expr): predicated expression_list :=
+Fixpoint merge (pel: list apred_expr): apredicated expression_list :=
match pel with
| nil => NE.singleton (T, Enil)
| a :: b => merge' a (merge b)
end.
-Definition map_predicated {A B} (pf: predicated (A -> B)) (pa: predicated A)
- : predicated B :=
+Definition map_predicated {A B} (pf: apredicated (A -> B)) (pa: apredicated A)
+ : apredicated B :=
predicated_map (fun x => (fst x) (snd x)) (predicated_prod pf pa).
-Definition predicated_apply1 {A B} (pf: predicated (A -> B)) (pa: A)
- : predicated B :=
+Definition predicated_apply1 {A B} (pf: apredicated (A -> B)) (pa: A)
+ : apredicated B :=
NE.map (fun x => (fst x, (snd x) pa)) pf.
-Definition predicated_apply2 {A B C} (pf: predicated (A -> B -> C)) (pa: A)
- (pb: B): predicated C :=
+Definition predicated_apply2 {A B C} (pf: apredicated (A -> B -> C)) (pa: A)
+ (pb: B): apredicated C :=
NE.map (fun x => (fst x, (snd x) pa pb)) pf.
-Definition predicated_apply3 {A B C D} (pf: predicated (A -> B -> C -> D))
- (pa: A) (pb: B) (pc: C): predicated D :=
+Definition predicated_apply3 {A B C D} (pf: apredicated (A -> B -> C -> D))
+ (pa: A) (pb: B) (pc: C): apredicated D :=
NE.map (fun x => (fst x, (snd x) pa pb pc)) pf.
-Definition predicated_from_opt {A: Type} (p: option pred_op) (a: A) :=
+Definition predicated_from_opt {A: Type} (p: option apred_op) (a: A) :=
match p with
| Some p' => NE.singleton (p', a)
| None => NE.singleton (T, a)
@@ -137,18 +143,19 @@ Fixpoint NEapp {A} (l m: NE.non_empty A) :=
| a ::| b => a ::| NEapp b m
end.
-Definition app_predicated' {A: Type} (a b: predicated A) :=
+Definition app_predicated' {A: Type} (a b: apredicated A) :=
let negation := ¬ (NEfold_left (fun a b => a ∨ (fst b)) b ⟂) in
NEapp (NE.map (fun x => (negation ∧ fst x, snd x)) a) b.
-Definition app_predicated {A: Type} (p: option pred_op) (a b: predicated A) :=
- match p with
- | Some p' => NEapp (NE.map (fun x => (¬ p' ∧ fst x, snd x)) a)
- (NE.map (fun x => (p' ∧ fst x, snd x)) b)
- | None => b
- end.
+Definition app_predicated {A: Type} (p': apred_op) (a b: apredicated A) :=
+ NEapp (NE.map (fun x => (¬ p' ∧ fst x, snd x)) a)
+ (NE.map (fun x => (p' ∧ fst x, snd x)) b).
-Definition pred_ret {A: Type} (a: A) : predicated A :=
+Definition prune_predicated {A: Type} (a: apredicated A) :=
+ NE.filter (fun x => match deep_simplify expression_dec (fst x) with ⟂ => false | _ => true end)
+ (NE.map (fun x => (deep_simplify expression_dec (fst x), snd x)) a).
+
+Definition pred_ret {A: Type} (a: A) : apredicated A :=
NE.singleton (T, a).
(*|
@@ -167,53 +174,105 @@ This is done by multiplying the predicates together, and assigning the negation
of the expression to the other predicates.
|*)
-Definition upd_pred_forest (p: option pred_op) (f: forest) :=
- match p with
- | Some p' =>
- PTree.map (fun i e =>
- NE.map (fun (x: pred_op * expression) =>
- let (pred, expr) := x in
- (Pand p' pred, expr)
- ) e) f
- | None => f
+Definition upd_pred_forest (p: apred_op) (f: forest) :=
+ PTree.map (fun i e =>
+ NE.map (fun (x: apred_op * expression) =>
+ let (pred, expr) := x in
+ (Pand p pred, expr)) e) f.
+
+Fixpoint apredicated_to_apred_op (b: bool) (a: apredicated expression): apred_op :=
+ match a with
+ | NE.singleton (p, e) => Pimplies p (Plit (b, e))
+ | (p, e) ::| r =>
+ Pand (Pimplies p (Plit (true, e))) (apredicated_to_apred_op b r)
+ end.
+
+(* Fixpoint get_pred' (f: forest) (ap: pred_op): option apred_op := *)
+(* match ap with *)
+(* | Ptrue => Some Ptrue *)
+(* | Pfalse => Some Pfalse *)
+(* | Plit (a, b) => *)
+(* match f # (Pred b) with *)
+(* | NE.singleton (Ptrue, p) => Some (Plit (a, p)) *)
+(* | _ => None *)
+(* end *)
+(* | Pand a b => match (get_pred' f a), (get_pred' f b) with *)
+(* | Some a', Some b' => Some (Pand a' b') *)
+(* | _, _ => None *)
+(* end *)
+(* | Por a b => match (get_pred' f a), (get_pred' f b) with *)
+(* | Some a', Some b' => Some (Por a' b') *)
+(* | _, _ => None *)
+(* end *)
+(* end. *)
+
+(* Definition get_pred (f: forest) (ap: option pred_op): option apred_op := *)
+(* get_pred' f (Option.default T ap). *)
+
+Fixpoint get_pred' (f: forest) (ap: pred_op): apred_op :=
+ match ap with
+ | Ptrue => Ptrue
+ | Pfalse => Pfalse
+ | Plit (a, b) =>
+ apredicated_to_apred_op a (f # (Pred b))
+ | Pand a b => Pand (get_pred' f a) (get_pred' f b)
+ | Por a b => Por (get_pred' f a) (get_pred' f b)
end.
-Definition update (fop : option pred_op * forest) (i : instr): (option pred_op * forest) :=
- let (pred, f) := fop in
+Definition get_pred (f: forest) (ap: option pred_op): apred_op :=
+ get_pred' f (Option.default Ptrue ap).
+
+#[local] Open Scope monad_scope.
+
+Definition simpl_combine {A: Type} (a b: option (@Predicate.pred_op A)) :=
+ Option.map simplify (combine_pred a b).
+
+Definition update (fop : option (apred_op * forest)) (i : instr): option (apred_op * forest) :=
+ do (pred, f) <- fop;
match i with
| RBnop => fop
| RBop p op rl r =>
- (pred, f # (Reg r) <-
- (app_predicated (combine_pred p pred)
+ do pruned <-
+ prune_predicated
+ (app_predicated (get_pred f p ∧ pred)
(f # (Reg r))
- (map_predicated (pred_ret (Eop op)) (merge (list_translation rl f)))))
+ (map_predicated (pred_ret (Eop op)) (merge (list_translation rl f))));
+ Some (pred, f # (Reg r) <- pruned)
| RBload p chunk addr rl r =>
- (pred, f # (Reg r) <-
- (app_predicated (combine_pred p pred)
- (f # (Reg r))
- (map_predicated
- (map_predicated (pred_ret (Eload chunk addr))
- (merge (list_translation rl f)))
- (f # Mem))))
+ do pruned <-
+ prune_predicated
+ (app_predicated (get_pred f p ∧ pred)
+ (f # (Reg r))
+ (map_predicated
+ (map_predicated (pred_ret (Eload chunk addr))
+ (merge (list_translation rl f)))
+ (f # Mem)));
+ Some (pred, f # (Reg r) <- pruned)
| RBstore p chunk addr rl r =>
- (pred, f # Mem <-
- (app_predicated (combine_pred p pred)
- (f # Mem)
- (map_predicated
- (map_predicated
- (predicated_apply2 (map_predicated (pred_ret Estore)
- (f # (Reg r))) chunk addr)
- (merge (list_translation rl f))) (f # Mem))))
+ do pruned <-
+ prune_predicated
+ (app_predicated (get_pred f p ∧ pred)
+ (f # Mem)
+ (map_predicated
+ (map_predicated
+ (predicated_apply2 (map_predicated (pred_ret Estore)
+ (f # (Reg r))) chunk addr)
+ (merge (list_translation rl f))) (f # Mem)));
+ Some (pred, f # Mem <- pruned)
| RBsetpred p' c args p =>
- (pred, f # (Pred p) <-
- (app_predicated (combine_pred p' pred)
- (f # (Pred p))
- (map_predicated (pred_ret (Esetpred c))
- (merge (list_translation args f)))))
+ do pruned <-
+ prune_predicated
+ (app_predicated (get_pred f p' ∧ pred)
+ (f # (Pred p))
+ (map_predicated (pred_ret (Esetpred c))
+ (merge (list_translation args f))));
+ Some (pred, f # (Pred p) <- pruned)
| RBexit p c =>
- (combine_pred (Some (negate (Option.default T p))) pred,
- f # Exit <-
- (app_predicated (combine_pred p pred) (f # Exit) (pred_ret (Eexit c))))
+ let new_p := simplify (get_pred' f (negate (Option.default T p)) ∧ pred) in
+ do pruned <-
+ prune_predicated
+ (app_predicated (get_pred f p ∧ pred) (f # Exit) (pred_ret (Eexit c)));
+ Some (new_p, f # Exit <- pruned)
end.
(*|
@@ -224,8 +283,8 @@ code than in the RTLBlock code.
Get a sequence from the basic block.
|*)
-Definition abstract_sequence (b : list instr) : forest :=
- snd (fold_left update b (None, empty)).
+Definition abstract_sequence (b : list instr) : option forest :=
+ Option.map snd (fold_left update b (Some (Ptrue, empty))).
(*|
Check equivalence of control flow instructions. As none of the basic blocks
@@ -252,8 +311,11 @@ Definition empty_trees (bb: SeqBB.t) (bbt: ParBB.t) : bool :=
end.
Definition schedule_oracle (bb: SeqBB.t) (bbt: ParBB.t) : bool :=
- (check (abstract_sequence bb) (abstract_sequence (concat (concat bbt))))
- && empty_trees bb bbt.
+ match abstract_sequence bb, abstract_sequence (concat (concat bbt)) with
+ | Some bb', Some bbt' =>
+ check bb' bbt' && empty_trees bb bbt
+ | _, _ => false
+ end.
Definition check_scheduled_trees := beq2 schedule_oracle.
diff --git a/src/hls/GiblePargenproof.v b/src/hls/GiblePargenproof.v
index 955902c..84a128a 100644
--- a/src/hls/GiblePargenproof.v
+++ b/src/hls/GiblePargenproof.v
@@ -106,7 +106,7 @@ Proof. induction l; crush. Qed.
Lemma check_dest_l_dec i r : {check_dest_l i r = true} + {check_dest_l i r = false}.
Proof. destruct (check_dest_l i r); tauto. Qed.
-Lemma check_dest_update :
+(*Lemma check_dest_update :
forall f i r,
check_dest i r = false ->
(snd (update f i)) # (Reg r) = (snd f) # (Reg r).
@@ -1162,13 +1162,13 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
sem (mk_ctx i sp ge) (snd (update (p, f) a)) (i'', None).
Proof. Admitted.
- Lemma sem_update_instr_term :
+(* Lemma sem_update_instr_term :
forall f i' i'' a sp i cf p p',
sem (mk_ctx i sp ge) f (i', None) ->
step_instr ge sp (Iexec i') (RBexit p cf) (Iterm i'' cf) ->
sem (mk_ctx i sp ge) (snd (update (p', f) a)) (i'', Some cf)
/\ falsy (is_ps i'') (fst (update (p', f) a)).
- Proof. Admitted.
+ Proof. Admitted.*)
Lemma step_instr_lessdef :
forall sp a i i' ti,
@@ -1184,7 +1184,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
exists ti', step_instr ge sp (Iexec ti) a (Iterm ti' cf) /\ state_lessdef i' ti'.
Proof. Admitted.
- Lemma app_predicated_semregset :
+(* Lemma app_predicated_semregset :
forall A ctx o f res r y,
@sem_regset A ctx f res ->
falsy (ctx_ps ctx) o ->
@@ -1212,7 +1212,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
Proof.
inversion 1; subst; crush.
constructor.
- Admitted.
+ Admitted.*)
Lemma combined_falsy :
forall i o1 o,
@@ -1224,7 +1224,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
constructor. auto.
Qed.
- Lemma falsy_update :
+ (*Lemma falsy_update :
forall f a ps,
falsy ps (fst f) ->
falsy ps (fst (update f a)).
@@ -1306,7 +1306,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
Proof.
unfold abstract_sequence. intros; eapply abstr_fold_correct; eauto.
simplify. eapply sem_empty.
- Qed.
+ Qed.*)
Lemma abstr_check_correct :
forall sp i i' a b cf ti,
@@ -1333,7 +1333,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
exists ti', ParBB.step tge sp (Iexec ti) y (Iterm ti' cf)
/\ state_lessdef i' ti'.
Proof.
- unfold schedule_oracle; intros. simplify.
+ (*unfold schedule_oracle; intros. simplify.
exploit abstr_sequence_correct; eauto; simplify.
exploit abstr_check_correct; eauto. apply state_lessdef_refl. simplify.
exploit abstr_seq_reverse_correct; eauto. apply state_lessdef_refl. simplify.
@@ -1341,7 +1341,7 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
econstructor; split; eauto.
etransitivity; eauto.
etransitivity; eauto.
- Qed.
+ Qed.*) Admitted.
Lemma step_cf_correct :
forall cf ts s s' t,
@@ -1422,4 +1422,4 @@ Proof. induction 2; try rewrite H; eauto with barg. Qed.
exact transl_step_correct.
Qed.
-End CORRECTNESS.
+End CORRECTNESS.*)
diff --git a/src/hls/HTLPargen.v b/src/hls/HTLPargen.v
index d9a2b48..b602ab6 100644
--- a/src/hls/HTLPargen.v
+++ b/src/hls/HTLPargen.v
@@ -102,6 +102,7 @@ Export HTLMonad.
Module HTLMonadExtra := Monad.MonadExtra(HTLMonad).
Import HTLMonadExtra.
Export MonadNotation.
+#[local] Open Scope monad_scope.
Fixpoint pred_expr (preg: reg) (p: pred_op) :=
match p with
diff --git a/src/hls/HTLgen.v b/src/hls/HTLgen.v
index c793b1b..bff68a2 100644
--- a/src/hls/HTLgen.v
+++ b/src/hls/HTLgen.v
@@ -99,6 +99,7 @@ Export HTLMonad.
Module HTLMonadExtra := Monad.MonadExtra(HTLMonad).
Import HTLMonadExtra.
Export MonadNotation.
+#[local] Open Scope monad_scope.
Definition state_goto (st : reg) (n : node) : stmnt :=
Vnonblock (Vvar st) (Vlit (posToValue n)).
diff --git a/src/hls/HashTree.v b/src/hls/HashTree.v
index 9f9ec81..80a7825 100644
--- a/src/hls/HashTree.v
+++ b/src/hls/HashTree.v
@@ -21,6 +21,8 @@ Require Import Coq.Structures.Equalities.
Require Import compcert.lib.Maps.
Require Import vericert.common.Vericertlib.
+Require Import vericert.common.Monad.
+Require Import vericert.common.Statemonad.
#[local] Open Scope positive.
@@ -432,4 +434,28 @@ Module HashTree(H: Hashable).
by (apply max_not_present; lia). crush.
Qed.
+ Module HashState <: State.
+ Definition st := hash_tree.
+ Definition st_prop (h1 h2: hash_tree): Prop :=
+ forall x y, h1 ! x = Some y -> h2 ! x = Some y.
+
+ Lemma st_refl :
+ forall s, st_prop s s.
+ Proof. unfold st_prop; auto. Qed.
+
+ Lemma st_trans :
+ forall s1 s2 s3,
+ st_prop s1 s2 -> st_prop s2 s3 -> st_prop s1 s3.
+ Proof.
+ unfold st_prop; intros; eauto.
+ Qed.
+
+ #[export] Instance HashStatePreorder : PreOrder st_prop :=
+ { PreOrder_Reflexive := st_refl;
+ PreOrder_Transitive := st_trans;
+ }.
+ End HashState.
+
+ Module HashMonad := Statemonad(HashState).
+
End HashTree.
diff --git a/src/hls/PipelineOp.v b/src/hls/PipelineOp.v
index 63d7d5a..90ccea0 100644
--- a/src/hls/PipelineOp.v
+++ b/src/hls/PipelineOp.v
@@ -31,8 +31,10 @@ Require Import vericert.common.Vericertlib.
Require Import vericert.hls.Gible.
Require Import vericert.hls.GiblePar.
Require Import vericert.hls.FunctionalUnits.
+Require Import vericert.common.Monad.
-Import Option.Notation.
+Module OptionExtra := MonadExtra(Option).
+Import OptionExtra.MonadNotation.
Local Open Scope positive.
diff --git a/src/hls/Predicate.v b/src/hls/Predicate.v
index b9333d9..8dbd0f6 100644
--- a/src/hls/Predicate.v
+++ b/src/hls/Predicate.v
@@ -7,22 +7,142 @@ Require Import Coq.Logic.Decidable.
Require Import vericert.common.Vericertlib.
Require Import vericert.hls.Sat.
-
-Definition predicate : Type := positive.
-
-Inductive pred_op : Type :=
-| Plit: (bool * predicate) -> pred_op
-| Ptrue: pred_op
-| Pfalse: pred_op
-| Pand: pred_op -> pred_op -> pred_op
-| Por: pred_op -> pred_op -> pred_op.
+Require Import HashTree.
Declare Scope pred_op.
+Section PRED_DEFINITION.
+
+ Context {A: Type}.
+
+ Definition predicate := A.
+
+ Inductive pred_op : Type :=
+ | Plit: (bool * predicate) -> pred_op
+ | Ptrue: pred_op
+ | Pfalse: pred_op
+ | Pand: pred_op -> pred_op -> pred_op
+ | Por: pred_op -> pred_op -> pred_op.
+
+ Fixpoint negate (p: pred_op) :=
+ match p with
+ | Plit (b, pr) => Plit (negb b, pr)
+ | Ptrue => Pfalse
+ | Pfalse => Ptrue
+ | Pand A B => Por (negate A) (negate B)
+ | Por A B => Pand (negate A) (negate B)
+ end.
+
+ Definition Pimplies (p: pred_op) p' := Por (negate p) p'.
+
+ Fixpoint predicate_use (p: pred_op) : list predicate :=
+ match p with
+ | Plit (b, p) => p :: nil
+ | Ptrue => nil
+ | Pfalse => nil
+ | Pand a b => predicate_use a ++ predicate_use b
+ | Por a b => predicate_use a ++ predicate_use b
+ end.
+
+ Definition combine_pred (p1 p2: option pred_op): option pred_op :=
+ match p1, p2 with
+ | Some p1, Some p2 => Some (Pand p1 p2)
+ | Some p, _ | _, Some p => Some p
+ | None, None => None
+ end.
+
+ Definition simplify' (p: pred_op) :=
+ match p with
+ (* | (Plit (b1, a)) ∧ (Plit (b2, b)) as p' => *)
+ (* if Pos.eqb a b then *)
+ (* if negb (xorb b1 b2) then Plit (b1, a) else ⟂ *)
+ (* else p' *)
+ (* | (Plit (b1, a)) ∨ (Plit (b2, b)) as p' => *)
+ (* if Pos.eqb a b then *)
+ (* if negb (xorb b1 b2) then Plit (b1, a) else T *)
+ (* else p' *)
+ | Pand A Ptrue => A
+ | Pand Ptrue A => A
+ | Pand _ Pfalse => Pfalse
+ | Pand Pfalse _ => Pfalse
+ | Por _ Ptrue => Ptrue
+ | Por Ptrue _ => Ptrue
+ | Por A Pfalse => A
+ | Por Pfalse A => A
+ | A => A
+ end.
+
+ Fixpoint simplify (p: pred_op) :=
+ match p with
+ | Pand A B =>
+ let A' := simplify A in
+ let B' := simplify B in
+ simplify' (Pand A' B')
+ | Por A B =>
+ let A' := simplify A in
+ let B' := simplify B in
+ simplify' (Por A' B')
+ | Ptrue => Ptrue
+ | Pfalse => Pfalse
+ | Plit a => Plit a
+ end.
+
+ Section DEEP_SIMPLIFY.
+
+ Context (eqd: forall a b: A, {a = b} + {a <> b}).
+
+ Definition deep_simplify' (p: pred_op) :=
+ match p with
+ | Pand A Ptrue => A
+ | Pand Ptrue A => A
+ | Pand _ Pfalse => Pfalse
+ | Pand Pfalse _ => Pfalse
+ | Por _ Ptrue => Ptrue
+ | Por Ptrue _ => Ptrue
+ | Por A Pfalse => A
+ | Por Pfalse A => A
+
+ | Pand (Plit (b1, a)) (Plit (b2, b)) =>
+ if eqd a b then
+ if bool_eqdec b1 b2 then
+ Plit (b1, a)
+ else Pfalse
+ else Pand (Plit (b1, a)) (Plit (b2, b))
+ | Por (Plit (b1, a)) (Plit (b2, b)) =>
+ if eqd a b then
+ if bool_eqdec b1 b2 then
+ Plit (b1, a)
+ else Ptrue
+ else Por (Plit (b1, a)) (Plit (b2, b))
+
+ | A => A
+ end.
+
+ Fixpoint deep_simplify (p: pred_op) :=
+ match p with
+ | Pand A B =>
+ let A' := deep_simplify A in
+ let B' := deep_simplify B in
+ deep_simplify' (Pand A' B')
+ | Por A B =>
+ let A' := deep_simplify A in
+ let B' := deep_simplify B in
+ deep_simplify' (Por A' B')
+ | Ptrue => Ptrue
+ | Pfalse => Pfalse
+ | Plit a => Plit a
+ end.
+
+ End DEEP_SIMPLIFY.
+
+End PRED_DEFINITION.
+
Notation "A ∧ B" := (Pand A B) (at level 20) : pred_op.
Notation "A ∨ B" := (Por A B) (at level 25) : pred_op.
Notation "⟂" := (Pfalse) : pred_op.
Notation "'T'" := (Ptrue) : pred_op.
+Notation "¬ A" := (negate A) (at level 15) : pred_op.
+Notation "A → B" := (Pimplies A B) (at level 30) : pred_op.
#[local] Open Scope pred_op.
@@ -47,18 +167,18 @@ Lemma equiv_refl : forall a, sat_equiv a a.
Proof. crush. Qed.
#[global]
-Instance Equivalence_SAT : Equivalence sat_equiv :=
+ Instance Equivalence_SAT : Equivalence sat_equiv :=
{ Equivalence_Reflexive := equiv_refl ;
Equivalence_Symmetric := equiv_symm ;
Equivalence_Transitive := equiv_trans ;
}.
#[global]
-Instance SATSetoid : Setoid pred_op :=
+ Instance SATSetoid : Setoid pred_op :=
{ equiv := sat_equiv; }.
#[global]
-Instance PandProper : Proper (equiv ==> equiv ==> equiv) Pand.
+ Instance PandProper : Proper (equiv ==> equiv ==> equiv) Pand.
Proof.
unfold Proper. simplify. unfold "==>".
intros.
@@ -68,7 +188,7 @@ Proof.
Qed.
#[global]
-Instance PorProper : Proper (equiv ==> equiv ==> equiv) Por.
+ Instance PorProper : Proper (equiv ==> equiv ==> equiv) Por.
Proof.
unfold Proper, "==>". simplify.
intros.
@@ -78,7 +198,7 @@ Proof.
Qed.
#[global]
-Instance sat_predicate_Proper : Proper (equiv ==> eq ==> eq) sat_predicate.
+ Instance sat_predicate_Proper : Proper (equiv ==> eq ==> eq) sat_predicate.
Proof.
unfold Proper, "==>". simplify.
intros.
@@ -86,19 +206,8 @@ Proof.
apply H.
Qed.
-Fixpoint negate (p: pred_op) :=
- match p with
- | Plit (b, pr) => Plit (negb b, pr)
- | T => ⟂
- | ⟂ => T
- | A ∧ B => negate A ∨ negate B
- | A ∨ B => negate A ∧ negate B
- end.
-
-Notation "¬ A" := (negate A) (at level 15) : pred_op.
-
Lemma negate_correct :
- forall h a, sat_predicate (negate h) a = negb (sat_predicate h a).
+ forall (h: @pred_op positive) a, sat_predicate (negate h) a = negb (sat_predicate h a).
Proof.
induction h; crush.
- repeat destruct_match; subst; crush; symmetry; apply negb_involutive.
@@ -150,8 +259,8 @@ Proof.
intros. specialize (H c); simplify.
rewrite negate_correct in *.
destruct (sat_predicate b c) eqn:X;
- destruct (sat_predicate a c) eqn:X2;
- crush.
+ destruct (sat_predicate a c) eqn:X2;
+ crush.
Qed.
Lemma sat_predicate_and :
@@ -183,8 +292,8 @@ Proof.
specialize (H c); simplify.
rewrite negate_correct in *.
destruct (sat_predicate b c) eqn:X;
- destruct (sat_predicate a c) eqn:X2;
- crush.
+ destruct (sat_predicate a c) eqn:X2;
+ crush.
Qed.
Lemma sat_equiv4 :
@@ -197,52 +306,16 @@ Proof.
rewrite andb_negb_r. auto.
Qed.
-Definition simplify' (p: pred_op) :=
- match p with
- | (Plit (b1, a)) ∧ (Plit (b2, b)) as p' =>
- if Pos.eqb a b then
- if negb (xorb b1 b2) then Plit (b1, a) else ⟂
- else p'
- | (Plit (b1, a)) ∨ (Plit (b2, b)) as p' =>
- if Pos.eqb a b then
- if negb (xorb b1 b2) then Plit (b1, a) else T
- else p'
- | A ∧ T => A
- | T ∧ A => A
- | _ ∧ ⟂ => ⟂
- | ⟂ ∧ _ => ⟂
- | _ ∨ T => T
- | T ∨ _ => T
- | A ∨ ⟂ => A
- | ⟂ ∨ A => A
- | A => A
- end.
-
Lemma pred_op_dec :
- forall p1 p2: pred_op,
- { p1 = p2 } + { p1 <> p2 }.
+ forall p1 p2: @pred_op positive,
+ { p1 = p2 } + { p1 <> p2 }.
Proof. pose proof Pos.eq_dec. repeat decide equality. Qed.
-Fixpoint simplify (p: pred_op) :=
- match p with
- | A ∧ B =>
- let A' := simplify A in
- let B' := simplify B in
- simplify' (A' ∧ B')
- | A ∨ B =>
- let A' := simplify A in
- let B' := simplify B in
- simplify' (A' ∨ B')
- | T => T
- | ⟂ => ⟂
- | Plit a => Plit a
- end.
-
Lemma simplify'_correct :
forall h a,
sat_predicate (simplify' h) a = sat_predicate h a.
Proof.
- (*destruct h; crush; repeat destruct_match; crush;
+(*destruct h; crush; repeat destruct_match; crush;
solve [rewrite andb_true_r; auto | rewrite orb_false_r; auto].
Qed.*) Admitted.
@@ -271,15 +344,15 @@ Fixpoint mult {A: Type} (a b: list (list A)) : list (list A) :=
Lemma satFormula_concat:
forall a b agn,
- satFormula a agn ->
- satFormula b agn ->
- satFormula (a ++ b) agn.
+ satFormula a agn ->
+ satFormula b agn ->
+ satFormula (a ++ b) agn.
Proof. induction a; crush. Qed.
Lemma satFormula_concat2:
forall a b agn,
- satFormula (a ++ b) agn ->
- satFormula a agn /\ satFormula b agn.
+ satFormula (a ++ b) agn ->
+ satFormula a agn /\ satFormula b agn.
Proof.
induction a; simplify;
try apply IHa in H1; crush.
@@ -287,14 +360,14 @@ Qed.
Lemma satClause_concat:
forall a a1 a0,
- satClause a a1 ->
- satClause (a0 ++ a) a1.
+ satClause a a1 ->
+ satClause (a0 ++ a) a1.
Proof. induction a0; crush. Qed.
Lemma satClause_concat2:
forall a a1 a0,
- satClause a0 a1 ->
- satClause (a0 ++ a) a1.
+ satClause a0 a1 ->
+ satClause (a0 ++ a) a1.
Proof.
induction a0; crush.
inv H; crush.
@@ -302,8 +375,8 @@ Qed.
Lemma satClause_concat3:
forall a b c,
- satClause (a ++ b) c ->
- satClause a c \/ satClause b c.
+ satClause (a ++ b) c ->
+ satClause a c \/ satClause b c.
Proof.
induction a; crush.
inv H; crush.
@@ -313,8 +386,8 @@ Qed.
Lemma satFormula_mult':
forall p2 a a0,
- satFormula p2 a0 \/ satClause a a0 ->
- satFormula (map (fun x : list lit => a ++ x) p2) a0.
+ satFormula p2 a0 \/ satClause a a0 ->
+ satFormula (map (fun x : list lit => a ++ x) p2) a0.
Proof.
induction p2; crush.
- inv H. inv H0. apply satClause_concat. auto.
@@ -325,8 +398,8 @@ Qed.
Lemma satFormula_mult2':
forall p2 a a0,
- satFormula (map (fun x : list lit => a ++ x) p2) a0 ->
- satClause a a0 \/ satFormula p2 a0.
+ satFormula (map (fun x : list lit => a ++ x) p2) a0 ->
+ satClause a a0 \/ satFormula p2 a0.
Proof.
induction p2; crush.
apply IHp2 in H1. inv H1; crush.
@@ -336,8 +409,8 @@ Qed.
Lemma satFormula_mult:
forall p1 p2 a,
- satFormula p1 a \/ satFormula p2 a ->
- satFormula (mult p1 p2) a.
+ satFormula p1 a \/ satFormula p2 a ->
+ satFormula (mult p1 p2) a.
Proof.
induction p1; crush.
apply satFormula_concat; crush.
@@ -345,13 +418,13 @@ Proof.
apply IHp1. auto.
apply IHp1. auto.
apply satFormula_mult';
- inv H; crush.
+ inv H; crush.
Qed.
Lemma satFormula_mult2:
forall p1 p2 a,
- satFormula (mult p1 p2) a ->
- satFormula p1 a \/ satFormula p2 a.
+ satFormula (mult p1 p2) a ->
+ satFormula p1 a \/ satFormula p2 a.
Proof.
induction p1; crush.
apply satFormula_concat2 in H; crush.
@@ -364,19 +437,19 @@ Fixpoint trans_pred (p: pred_op) :
{fm: formula | forall a,
sat_predicate p a = true <-> satFormula fm a}.
refine
- (match p with
+ (match p with
| Plit (b, p') => exist _ (((b, Pos.to_nat p') :: nil) :: nil) _
| Ptrue => exist _ nil _
| Pfalse => exist _ (nil::nil) _
| Pand p1 p2 =>
- match trans_pred p1, trans_pred p2 with
- | exist _ p1' _, exist _ p2' _ => exist _ (p1' ++ p2') _
- end
+ match trans_pred p1, trans_pred p2 with
+ | exist _ p1' _, exist _ p2' _ => exist _ (p1' ++ p2') _
+ end
| Por p1 p2 =>
- match trans_pred p1, trans_pred p2 with
- | exist _ p1' _, exist _ p2' _ => exist _ (mult p1' p2') _
- end
- end); split; intros; simpl in *; auto; try solve [crush].
+ match trans_pred p1, trans_pred p2 with
+ | exist _ p1' _, exist _ p2' _ => exist _ (mult p1' p2') _
+ end
+ end); split; intros; simpl in *; auto; try solve [crush].
- destruct b; auto. apply negb_true_iff in H. auto.
- destruct b. inv H. inv H0; auto. apply negb_true_iff. inv H. inv H0; eauto. contradiction.
- apply satFormula_concat.
@@ -492,8 +565,8 @@ Proof.
assert
(satFormula
(((true, n1) :: bar l0 :: bar l1 :: nil)
- :: (bar (true, n1) :: l0 :: nil)
- :: (bar (true, n1) :: l1 :: nil) :: nil) c).
+ :: (bar (true, n1) :: l0 :: nil)
+ :: (bar (true, n1) :: l1 :: nil) :: nil) c).
eapply stseytin_and_correct. unfold stseytin_and. eauto.
unfold satLit. simpl. admit.
inv H; try contradiction. inv H1; try contradiction. eauto.
@@ -508,15 +581,6 @@ Fixpoint max_predicate (p: pred_op) : positive :=
| Por a b => Pos.max (max_predicate a) (max_predicate b)
end.
-Fixpoint predicate_use (p: pred_op) : list positive :=
- match p with
- | Plit (b, p) => p :: nil
- | Ptrue => nil
- | Pfalse => nil
- | Pand a b => predicate_use a ++ predicate_use b
- | Por a b => predicate_use a ++ predicate_use b
- end.
-
Definition tseytin (p: pred_op) :
{fm: formula | forall a,
sat_predicate p a = true <-> satFormula fm a}.
@@ -529,21 +593,21 @@ Definition tseytin (p: pred_op) :
intros. eapply xtseytin_correct; eauto. Defined.
Definition tseytin_simple (p: pred_op) : formula :=
- let m := Pos.to_nat (max_predicate p + 1) in
- let '(m, n, fm) := xtseytin m p in
- (n::nil) :: fm.
+ let m := Pos.to_nat (max_predicate p + 1) in
+ let '(m, n, fm) := xtseytin m p in
+ (n::nil) :: fm.
Definition sat_pred_tseytin (p: pred_op) :
({al : alist | sat_predicate p (interp_alist al) = true}
+ {forall a : asgn, sat_predicate p a = false}).
refine
- ( match tseytin p with
- | exist _ fm _ =>
- match satSolve fm with
- | inleft (exist _ a _) => inleft (exist _ a _)
- | inright _ => inright _
- end
- end ).
+ ( match tseytin p with
+ | exist _ fm _ =>
+ match satSolve fm with
+ | inleft (exist _ a _) => inleft (exist _ a _)
+ | inright _ => inright _
+ end
+ end ).
- apply i in s0. auto.
- intros. specialize (n a). specialize (i a).
destruct (sat_predicate p a). exfalso.
@@ -560,13 +624,13 @@ Definition sat_pred (p: pred_op) :
({al : alist | sat_predicate p (interp_alist al) = true}
+ {forall a : asgn, sat_predicate p a = false}).
refine
- ( match trans_pred p with
- | exist _ fm _ =>
- match satSolve fm with
- | inleft (exist _ a _) => inleft (exist _ a _)
- | inright _ => inright _
- end
- end ).
+ ( match trans_pred p with
+ | exist _ fm _ =>
+ match satSolve fm with
+ | inleft (exist _ a _) => inleft (exist _ a _)
+ | inright _ => inright _
+ end
+ end ).
- apply i in s0. auto.
- intros. specialize (n a). specialize (i a).
destruct (sat_predicate p a). exfalso.
@@ -651,15 +715,11 @@ Proof.
Qed.
#[global]
-Instance DecidableSATSetoid : DecidableSetoid SATSetoid :=
+ Instance DecidableSATSetoid : DecidableSetoid SATSetoid :=
{ setoid_decidable := equiv_check_decidable }.
#[global]
-Instance SATSetoidEqDec : EqDec SATSetoid := equiv_check_decidable2.
-
-Definition Pimplies p p' := ¬ p ∨ p'.
-
-Notation "A → B" := (Pimplies A B) (at level 30) : pred_op.
+ Instance SATSetoidEqDec : EqDec SATSetoid := equiv_check_decidable2.
Definition implies p p' :=
forall c, sat_predicate p c = true -> sat_predicate p' c = true.
@@ -674,7 +734,7 @@ Proof.
Qed.
#[global]
-Instance PimpliesProper : Proper (equiv ==> equiv ==> equiv) Pimplies.
+ Instance PimpliesProper : Proper (equiv ==> equiv ==> equiv) Pimplies.
Proof.
unfold Proper, "==>". simplify. unfold "→".
intros.
@@ -684,20 +744,13 @@ Proof.
Qed.
#[global]
-Instance simplifyProper : Proper (equiv ==> equiv) simplify.
+ Instance simplifyProper : Proper (equiv ==> equiv) simplify.
Proof.
unfold Proper, "==>". simplify. unfold "→".
intros. unfold sat_equiv; intros.
rewrite ! simplify_correct; auto.
Qed.
-Definition combine_pred (p1 p2: option pred_op): option pred_op :=
- match p1, p2 with
- | Some p1, Some p2 => Some (Pand p1 p2)
- | Some p, _ | _, Some p => Some p
- | None, None => None
- end.
-
Lemma predicate_lt :
forall p p0,
In p0 (predicate_use p) -> p0 <= max_predicate p.
diff --git a/src/hls/PrintAbstr.ml b/src/hls/PrintAbstr.ml
index c63fa02..c4a772e 100644
--- a/src/hls/PrintAbstr.ml
+++ b/src/hls/PrintAbstr.ml
@@ -1,18 +1,20 @@
-(**open Camlcoq
+open Camlcoq
open Datatypes
open Maps
open AST
open Abstr
open PrintAST
open Printf
+open Abstr
let rec expr_to_list = function
| Enil -> []
| Econs (e, el) -> e :: expr_to_list el
let res pp = function
- | Reg r -> fprintf pp "r%d" (P.to_int r)
+ | Reg r -> fprintf pp "x%d" (P.to_int r)
| Pred r -> fprintf pp "p%d" (P.to_int r)
+ | Exit -> fprintf pp "EXIT"
| Mem -> fprintf pp "M"
let rec print_expression pp = function
@@ -29,11 +31,29 @@ let rec print_expression pp = function
print_expression e
| Esetpred (c, el) ->
fprintf pp "(%a)" (PrintOp.print_condition print_expression) (c, expr_to_list el)
+ | Eexit cf ->
+ fprintf pp "[%a]" PrintGible.print_bblock_exit cf
+
+let rec rev_index = function
+ | BinNums.Coq_xH -> Mem
+ | BinNums.Coq_xO BinNums.Coq_xH -> Exit
+ | BinNums.Coq_xI (BinNums.Coq_xI r) -> Pred r
+ | BinNums.Coq_xO (BinNums.Coq_xO r) -> Reg r
+
+let print_pred_expr = PrintGible.print_pred_op_gen print_expression
let rec print_predicated pp = function
| NE.Coq_singleton (p, e) ->
- fprintf pp "%a %a" PrintRTLBlockInstr.print_pred_option p print_expression e
+ fprintf pp "%a %a" print_pred_expr p print_expression e
| NE.Coq_cons ((p, e), pr) ->
- fprintf pp "%a %a\n%a" PrintRTLBlockInstr.print_pred_option p print_expression e
+ fprintf pp "%a %a\n%a" print_pred_expr p print_expression e
print_predicated pr
-*)
+
+let print_forest pp f =
+ fprintf pp "########################################\n";
+ List.iter
+ (function (i, y) -> fprintf pp "-- %a --\n%a\n"
+ res (rev_index i)
+ print_predicated y)
+ (PTree.elements f);
+ flush stdout
diff --git a/src/hls/PrintGible.ml b/src/hls/PrintGible.ml
index 16d91af..a0dbaea 100644
--- a/src/hls/PrintGible.ml
+++ b/src/hls/PrintGible.ml
@@ -22,46 +22,48 @@ let ros pp = function
| Coq_inl r -> reg pp r
| Coq_inr s -> fprintf pp "\"%s\"" (extern_atom s)
-let rec print_pred_op pp = function
- | Plit p -> if fst p then pred pp (snd p) else fprintf pp "~%a" pred (snd p)
- | Pand (p1, p2) -> fprintf pp "(%a ∧ %a)" print_pred_op p1 print_pred_op p2
- | Por (p1, p2) -> fprintf pp "(%a ∨ %a)" print_pred_op p1 print_pred_op p2
+let rec print_pred_op_gen f pp = function
+ | Plit p -> if fst p then f pp (snd p) else fprintf pp "~%a" f (snd p)
+ | Pand (p1, p2) -> fprintf pp "(%a ∧ %a)" (print_pred_op_gen f) p1 (print_pred_op_gen f) p2
+ | Por (p1, p2) -> fprintf pp "(%a ∨ %a)" (print_pred_op_gen f) p1 (print_pred_op_gen f) p2
| Ptrue -> fprintf pp "T"
| Pfalse -> fprintf pp "⟂"
-let print_pred_option pp = function
- | Some x -> fprintf pp "(%a)" print_pred_op x
+let print_pred_option_gen f pp = function
+ | Some x -> fprintf pp "(%a)" (print_pred_op_gen f) x
| None -> ()
+let print_pred_option = print_pred_option_gen pred
+
let print_bblock_exit pp i =
match i with
| RBcall(_, fn, args, res, _) ->
- fprintf pp "%a = %a(%a)\n"
+ fprintf pp "%a = %a(%a)"
reg res ros fn regs args;
| RBtailcall(_, fn, args) ->
- fprintf pp "tailcall %a(%a)\n"
+ fprintf pp "tailcall %a(%a)"
ros fn regs args
| RBbuiltin(ef, args, res, _) ->
- fprintf pp "%a = %s(%a)\n"
+ fprintf pp "%a = %s(%a)"
(print_builtin_res reg) res
(name_of_external ef)
(print_builtin_args reg) args
| RBcond(cond, args, s1, s2) ->
- fprintf pp "if (%a) goto %d else goto %d\n"
+ fprintf pp "if (%a) goto %d else goto %d"
(PrintOp.print_condition reg) (cond, args)
(P.to_int s1) (P.to_int s2)
| RBjumptable(arg, tbl) ->
let tbl = Array.of_list tbl in
- fprintf pp "jumptable (%a)\n" reg arg;
+ fprintf pp "jumptable (%a)" reg arg;
for i = 0 to Array.length tbl - 1 do
- fprintf pp "\tcase %d: goto %d\n" i (P.to_int tbl.(i))
+ fprintf pp "\tcase %d: goto %d" i (P.to_int tbl.(i))
done
| RBreturn None ->
- fprintf pp "return\n"
+ fprintf pp "return"
| RBreturn (Some arg) ->
- fprintf pp "return %a\n" reg arg
+ fprintf pp "return %a" reg arg
| RBgoto n ->
- fprintf pp "goto %d\n" (P.to_int n)
+ fprintf pp "goto %d" (P.to_int n)
let print_bblock_body pp i =
fprintf pp "\t\t";
@@ -86,4 +88,4 @@ let print_bblock_body pp i =
pred p
(PrintOp.print_condition reg) (c, args)
| RBexit (p, cf) ->
- fprintf pp "%a %a" print_pred_option p print_bblock_exit cf
+ fprintf pp "%a %a\n" print_pred_option p print_bblock_exit cf
diff --git a/src/hls/RTLParFU.v b/src/hls/RTLParFU.v
index f0ceafd..fe48ac5 100644
--- a/src/hls/RTLParFU.v
+++ b/src/hls/RTLParFU.v
@@ -33,6 +33,8 @@ Require Import Predicate.
Require Import Vericertlib.
Definition node := positive.
+Definition predicate := positive.
+Definition pred_op := @pred_op predicate.
Inductive instr : Type :=
| FUnop : instr
diff --git a/test/Makefile b/test/Makefile
index 58a3c12..f037cea 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,6 @@
CC ?= gcc
VERICERT ?= vericert
-VERICERT_OPTS ?= -fschedule -fif-conv
+VERICERT_OPTS ?= -O0 -finline -fschedule -fif-conv -drtl -dgblseq -dgblpar
IVERILOG ?= iverilog
IVERILOG_OPTS ?=