aboutsummaryrefslogtreecommitdiff
path: root/src/Assembly/HL.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/Assembly/HL.v')
-rw-r--r--src/Assembly/HL.v91
1 files changed, 44 insertions, 47 deletions
diff --git a/src/Assembly/HL.v b/src/Assembly/HL.v
index b1147ccf8..e9eecd4c8 100644
--- a/src/Assembly/HL.v
+++ b/src/Assembly/HL.v
@@ -18,7 +18,7 @@ Module HL.
Context {var : type -> Type}.
Inductive expr : type -> Type :=
- | Const : @interp_type T TT -> expr TT
+ | Const : forall {_ : Evaluable T}, @interp_type T TT -> expr TT
| Var : forall {t}, var t -> expr t
| Binop : forall {t1 t2 t3}, binop t1 t2 t3 -> expr t1 -> expr t2 -> expr t3
| Let : forall {tx}, expr tx -> forall {tC}, (var tx -> expr tC) -> expr tC
@@ -26,11 +26,11 @@ Module HL.
| MatchPair : forall {t1 t2}, expr (Prod t1 t2) -> forall {tC}, (var t1 -> var t2 -> expr tC) -> expr tC.
End expr.
- Local Notation ZConst z := (@Const Z ZEvaluable _ z%Z).
+ Local Notation ZConst z := (@Const Z ConstEvaluable _ z%Z).
- Fixpoint interp {t} (e: @expr interp_type t) : interp_type t :=
+ Fixpoint interp {t} (e: @expr interp_type t) : @interp_type T t :=
match e in @expr _ t return interp_type t with
- | Const n => n
+ | Const _ x => x
| Var _ n => n
| Binop _ _ _ op e1 e2 => interp_binop op (interp e1) (interp e2)
| Let _ ex _ eC => dlet x := interp ex in interp (eC x)
@@ -40,29 +40,26 @@ Module HL.
Definition Expr t : Type := forall var, @expr var t.
- Definition Interp {t} (E: Expr t) : interp_type t := interp (E interp_type).
-
- Definition Expr' t : Type := forall var, (forall t', @interp_type Z t' -> var t') -> @expr var t.
-
- Definition Interp' {t} (f: Z -> T) (E: Expr' t) : interp_type t :=
- interp (E (@interp_type T) (fun t' x => typeMap (t := t') f x)).
+ Definition Interp {t} (e: Expr t) : interp_type t := interp (e interp_type).
End Language.
- Definition zinterp {n t} E := @interp Z (@ZEvaluable n) t E.
+ Definition zinterp {t} E := @interp Z ZEvaluable t E.
- Definition ZInterp {n t} E := @Interp Z (@ZEvaluable n) t E.
+ Definition ZInterp {t} E := @Interp Z ZEvaluable t E.
Definition wordInterp {n t} E := @interp (word n) (@WordEvaluable n) t E.
Definition WordInterp {n t} E := @Interp (word n) (@WordEvaluable n) t E.
+ Existing Instance ZEvaluable.
+
Example example_Expr : Expr TT := fun var => (
Let (Const 7) (fun a =>
Let (Let (Binop OPadd (Var a) (Var a)) (fun b => Pair (Var b) (Var b))) (fun p =>
MatchPair (Var p) (fun x y =>
Binop OPadd (Var x) (Var y)))))%Z.
- Example interp_example_Expr : ZInterp (n := 16) example_Expr = 28%Z.
+ Example interp_example_Expr : ZInterp example_Expr = 28%Z.
Proof. reflexivity. Qed.
(* Reification assumes the argument type is Z *)
@@ -85,68 +82,68 @@ Module HL.
| Z.shiftr => constr:(OPshiftr)
end.
- Class reify {varT} (var:varT) {eT} (e:eT) {T:Type} := Build_reify : T.
+ Class reify (n: nat) {varT} (var:varT) {eT} (e:eT) {T:Type} := Build_reify : T.
Definition reify_var_for_in_is {T} (x:T) (t:type) {eT} (e:eT) := False.
- Ltac reify var e :=
+ Ltac reify n var e :=
lazymatch e with
| let x := ?ex in @?eC x =>
- let ex := reify var ex in
- let eC := reify var eC in
- constr:(Let (T := Z) (var:=var) ex eC)
+ let ex := reify n var ex in
+ let eC := reify n var eC in
+ constr:(Let (T:=Z) (var:=var) ex eC)
| match ?ep with (v1, v2) => @?eC v1 v2 end =>
- let ep := reify var ep in
- let eC := reify var eC in
- constr:(MatchPair (T := Z) (var:=var) ep eC)
+ let ep := reify n var ep in
+ let eC := reify n var eC in
+ constr:(MatchPair (T:=Z) (var:=var) ep eC)
| pair ?a ?b =>
- let a := reify var a in
- let b := reify var b in
- constr:(Pair (T := Z) (var:=var) a b)
+ let a := reify n var a in
+ let b := reify n var b in
+ constr:(Pair (T:=Z) (var:=var) a b)
| ?op ?a ?b =>
let op := reify_binop op in
- let b := reify var b in
- let a := reify var a in
- constr:(Binop (T := Z) (var:=var) op a b)
+ let b := reify n var b in
+ let a := reify n var a in
+ constr:(Binop (T:=Z) (var:=var) op a b)
| (fun x : ?T => ?C) =>
let t := reify_type T in
(* Work around Coq 8.5 and 8.6 bug *)
(* <https://coq.inria.fr/bugs/show_bug.cgi?id=4998> *)
(* Avoid re-binding the Gallina variable referenced by Ltac [x] *)
(* even if its Gallina name matches a Ltac in this tactic. *)
+ (* [C] here is an open term that references "x" by name *)
let maybe_x := fresh x in
let not_x := fresh x in
lazymatch constr:(fun (x : T) (not_x : var t) (_:reify_var_for_in_is x t not_x) =>
- (_ : reify var C)) (* [C] here is an open term that references "x" by name *)
+ (_ : reify n var C))
with fun _ v _ => @?C v => C end
| ?x =>
lazymatch goal with
| _:reify_var_for_in_is x ?t ?v |- _ => constr:(@Var Z var t v)
- | _ =>
- let x' := eval cbv in x in
- match isZcst x' with
- | true => constr:(@Const Z var x)
- | false => constr:(@Var Z var TT x)
+ | _ => let x' := eval cbv in x in
+ match isZcst x with
+ | true => constr:(@Const Z var (@ConstEvaluable n) x)
+ | false => constr:(@Const Z var InputEvaluable x)
end
end
end.
- Hint Extern 0 (reify ?var ?e) => (let e := reify var e in eexact e) : typeclass_instances.
+ Hint Extern 0 (reify ?n ?var ?e) => (let e := reify n var e in eexact e) : typeclass_instances.
Ltac Reify e :=
- lazymatch constr:(fun (var:type->Type) => (_:reify var e)) with
- (fun var => ?C) => constr:(fun (var:type->Type) => C) (* copy the term but not the type cast *)
+ lazymatch constr:(fun (n: nat) (var:type->Type) => (_:reify n var e)) with
+ (fun n var => ?C) => constr:(fun (n: nat) (var:type->Type) => C) (* copy the term but not the type cast *)
end.
Definition zinterp_type := @interp_type Z.
Transparent zinterp_type.
- Goal forall (x : Z) (v : zinterp_type TT) (_:reify_var_for_in_is x TT v), reify(T:=Z) zinterp_type ((fun x => x+x) x)%Z.
+ Goal forall (x : Z) (v : zinterp_type TT) (_:reify_var_for_in_is x TT v), reify (T:=Z) 16 zinterp_type ((fun x => x+x) x)%Z.
intros.
- let A := (reify zinterp_type (x + x + 1)%Z) in pose A.
+ let A := (reify 16 zinterp_type (x + x + 1)%Z) in idtac A.
Abort.
Goal False.
- let z := reify zinterp_type (let x := 0 in x)%Z in pose z.
+ let z := (reify 16 zinterp_type (let x := 0 in x)%Z) in pose z.
Abort.
Ltac lhs_of_goal := match goal with |- ?R ?LHS ?RHS => constr:(LHS) end.
@@ -155,7 +152,7 @@ Module HL.
Ltac Reify_rhs n :=
let rhs := rhs_of_goal in
let RHS := Reify rhs in
- transitivity (ZInterp (n := n) RHS);
+ transitivity (ZInterp (RHS n));
[|cbv iota beta delta [ZInterp Interp interp_type interp_binop interp]; reflexivity].
Goal (0 = let x := 1+2 in x*3)%Z.
@@ -171,7 +168,7 @@ Module HL.
Local Notation "x ≡ y" := (existT _ _ (x, y)).
- Definition Texpr var t := @expr T var t.
+ Definition Texpr var t := @expr Z var t.
Inductive wf : list (sigT (fun t => var1 t * var2 t))%type -> forall {t}, Texpr var1 t -> Texpr var2 t -> Prop :=
| WfConst : forall G n, wf G (Const n) (Const n)
@@ -181,25 +178,25 @@ Module HL.
(op: binop t1 t2 t3),
wf G e1 e1'
-> wf G e2 e2'
- -> wf G (Binop (T := T) op e1 e2) (Binop (T := T) op e1' e2')
+ -> wf G (Binop op e1 e2) (Binop op e1' e2')
| WfLet : forall G t1 t2 e1 e1' (e2 : _ t1 -> Texpr _ t2) e2',
wf G e1 e1'
-> (forall x1 x2, wf ((x1 ≡ x2) :: G) (e2 x1) (e2' x2))
- -> wf G (Let (T := T) e1 e2) (Let (T := T) e1' e2')
+ -> wf G (Let e1 e2) (Let e1' e2')
| WfPair : forall G {t1} {t2} (e1: Texpr var1 t1) (e2: Texpr var1 t2)
(e1': Texpr var2 t1) (e2': Texpr var2 t2),
wf G e1 e1'
-> wf G e2 e2'
- -> wf G (Pair (T := T) e1 e2) (Pair (T := T) e1' e2')
+ -> wf G (Pair e1 e2) (Pair e1' e2')
| WfMatchPair : forall G t1 t2 tC ep ep' (eC : _ t1 -> _ t2 -> Texpr _ tC) eC',
wf G ep ep'
-> (forall x1 x2 y1 y2, wf ((x1 ≡ x2) :: (y1 ≡ y2) :: G) (eC x1 y1) (eC' x2 y2))
- -> wf G (MatchPair (T := T) ep eC) (MatchPair (T := T) ep' eC').
+ -> wf G (MatchPair ep eC) (MatchPair ep' eC').
End wf.
- Definition Wf {T: Type} {t} (E : @Expr T t) := forall var1 var2, wf nil (E var1) (E var2).
+ Definition Wf {T: Type} {t} (E : Expr t) := forall var1 var2, wf nil (E var1) (E var2).
- Example example_Expr_Wf : Wf example_Expr.
+ Example example_Expr_Wf : Wf (T := Z) example_Expr.
Proof.
unfold Wf; repeat match goal with
| [ |- wf _ _ _ ] => constructor