aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jason Gross <jgross@mit.edu>2017-01-11 21:02:50 -0500
committerGravatar Jason Gross <jasongross9@gmail.com>2017-03-01 11:45:47 -0500
commit6b3048c37ad348dc88ecc03ef892ecfb121bfa7f (patch)
tree351e5438c5664ab0caf08b9d5054f296ff4aa2ee
parent80dc66a34fbf031bfac1214ccbb3bb1dcdef3d39 (diff)
Switch to fully uncurried form for reflection
This will eventually make a number of proofs easier. Unfortunately, the correctness lemmas for AddCoordinates and LadderStep no longer work (because of different arities), and there's a proof in Experiments/Ed25519 that I've admitted. The correctness lemmas will be easy to re-add when we have a more general version that handle arbitrary type shapes.
-rw-r--r--_CoqProject3
-rw-r--r--src/Experiments/Ed25519.v54
-rw-r--r--src/Reflection/Application.v200
-rw-r--r--src/Reflection/ApplicationLemmas.v104
-rw-r--r--src/Reflection/ApplicationRelations.v28
-rw-r--r--src/Reflection/BoundByCast.v6
-rw-r--r--src/Reflection/BoundByCastInterp.v2
-rw-r--r--src/Reflection/CommonSubexpressionElimination.v7
-rw-r--r--src/Reflection/Conversion.v5
-rw-r--r--src/Reflection/CountLets.v12
-rw-r--r--src/Reflection/Equality.v9
-rw-r--r--src/Reflection/Eta.v18
-rw-r--r--src/Reflection/EtaInterp.v22
-rw-r--r--src/Reflection/EtaWf.v25
-rw-r--r--src/Reflection/ExprInversion.v69
-rw-r--r--src/Reflection/FilterLive.v11
-rw-r--r--src/Reflection/Inline.v5
-rw-r--r--src/Reflection/InlineCastInterp.v6
-rw-r--r--src/Reflection/InlineCastWf.v2
-rw-r--r--src/Reflection/InlineInterp.v45
-rw-r--r--src/Reflection/InlineWf.v30
-rw-r--r--src/Reflection/InputSyntax.v138
-rw-r--r--src/Reflection/InterpByIso.v10
-rw-r--r--src/Reflection/InterpByIsoProofs.v66
-rw-r--r--src/Reflection/InterpWf.v15
-rw-r--r--src/Reflection/InterpWfRel.v19
-rw-r--r--src/Reflection/Linearize.v5
-rw-r--r--src/Reflection/LinearizeInterp.v11
-rw-r--r--src/Reflection/LinearizeWf.v8
-rw-r--r--src/Reflection/MapCast.v33
-rw-r--r--src/Reflection/MapCastInterp.v60
-rw-r--r--src/Reflection/MapCastWf.v11
-rw-r--r--src/Reflection/MultiSizeTest2.v13
-rw-r--r--src/Reflection/Named/Compile.v11
-rw-r--r--src/Reflection/Named/EstablishLiveness.v9
-rw-r--r--src/Reflection/Named/RegisterAssign.v11
-rw-r--r--src/Reflection/Named/Syntax.v15
-rw-r--r--src/Reflection/Reify.v86
-rw-r--r--src/Reflection/Relations.v97
-rw-r--r--src/Reflection/SmartBound.v63
-rw-r--r--src/Reflection/SmartBoundInterp.v2
-rw-r--r--src/Reflection/SmartBoundWf.v101
-rw-r--r--src/Reflection/SmartMap.v69
-rw-r--r--src/Reflection/Syntax.v49
-rw-r--r--src/Reflection/TestCase.v29
-rw-r--r--src/Reflection/TypeInversion.v28
-rw-r--r--src/Reflection/Wf.v13
-rw-r--r--src/Reflection/WfInversion.v56
-rw-r--r--src/Reflection/WfProofs.v16
-rw-r--r--src/Reflection/WfReflective.v50
-rw-r--r--src/Reflection/WfReflectiveGen.v63
-rw-r--r--src/Reflection/Z/BoundsInterpretations.v25
-rw-r--r--src/Reflection/Z/CNotations.v42
-rw-r--r--src/Reflection/Z/Interpretations128/Relations.v11
-rw-r--r--src/Reflection/Z/Interpretations128/RelationsCombinations.v375
-rw-r--r--src/Reflection/Z/Interpretations64/Relations.v10
-rw-r--r--src/Reflection/Z/Interpretations64/RelationsCombinations.v375
-rw-r--r--src/Reflection/Z/InterpretationsGen.v183
-rw-r--r--src/Reflection/Z/JavaNotations.v42
-rw-r--r--src/Reflection/Z/OpInversion.v4
-rw-r--r--src/Reflection/Z/Reify.v31
-rw-r--r--src/Reflection/Z/Syntax.v46
-rw-r--r--src/Reflection/Z/Syntax/Equality.v127
-rw-r--r--src/Reflection/Z/Syntax/Util.v77
-rw-r--r--src/Specific/FancyMachine256/Barrett.v15
-rw-r--r--src/Specific/FancyMachine256/Montgomery.v17
-rw-r--r--src/Specific/GF25519Bounded.v128
-rw-r--r--src/Specific/GF25519BoundedAddCoordinates.v3
-rw-r--r--src/Specific/GF25519BoundedCommon.v44
-rw-r--r--src/Specific/GF25519BoundedExtendedAddCoordinates.v3
-rw-r--r--src/Specific/GF25519Reflective.v8
-rw-r--r--src/Specific/GF25519Reflective/Common.v440
-rw-r--r--src/Specific/GF25519Reflective/Common9_4Op.v32
-rw-r--r--src/Specific/GF25519Reflective/CommonBinOp.v20
-rw-r--r--src/Specific/GF25519Reflective/CommonUnOp.v7
-rw-r--r--src/Specific/GF25519Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/Specific/GF25519Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/Specific/GF25519Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/Specific/GF25519Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/Specific/GF25519Reflective/Reified/LadderStep.v207
-rw-r--r--src/Specific/GF25519Reflective/Reified/PreFreeze.v2
-rwxr-xr-xsrc/Specific/GF25519Reflective/Reified/rebuild-reified.py27
-rw-r--r--src/Specific/GF25519ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF2213_32Bounded.v128
-rw-r--r--src/SpecificGen/GF2213_32BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF2213_32BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF2213_32BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF2213_32Reflective.v8
-rw-r--r--src/SpecificGen/GF2213_32Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF2213_32Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF2213_32Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF2213_32Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF2213_32Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF2213_32Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF2213_32Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF2213_32Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF2213_32ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF2519_32Bounded.v128
-rw-r--r--src/SpecificGen/GF2519_32BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF2519_32BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF2519_32BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF2519_32Reflective.v8
-rw-r--r--src/SpecificGen/GF2519_32Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF2519_32Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF2519_32Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF2519_32Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF2519_32Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF2519_32Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF2519_32Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF2519_32Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF2519_32ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF25519_32Bounded.v128
-rw-r--r--src/SpecificGen/GF25519_32BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF25519_32BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF25519_32BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF25519_32Reflective.v8
-rw-r--r--src/SpecificGen/GF25519_32Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF25519_32Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF25519_32Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF25519_32Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF25519_32Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF25519_32Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF25519_32Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF25519_32Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF25519_32ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF25519_64Bounded.v128
-rw-r--r--src/SpecificGen/GF25519_64BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF25519_64BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF25519_64BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF25519_64Reflective.v8
-rw-r--r--src/SpecificGen/GF25519_64Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF25519_64Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF25519_64Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF25519_64Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF25519_64Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF25519_64Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF25519_64Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF25519_64Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF25519_64ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF41417_32Bounded.v128
-rw-r--r--src/SpecificGen/GF41417_32BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF41417_32BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF41417_32BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF41417_32Reflective.v8
-rw-r--r--src/SpecificGen/GF41417_32Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF41417_32Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF41417_32Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF41417_32Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF41417_32Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF41417_32Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF41417_32Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF41417_32Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF41417_32ReflectiveAddCoordinates.v5
-rw-r--r--src/SpecificGen/GF5211_32Bounded.v128
-rw-r--r--src/SpecificGen/GF5211_32BoundedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF5211_32BoundedCommon.v44
-rw-r--r--src/SpecificGen/GF5211_32BoundedExtendedAddCoordinates.v3
-rw-r--r--src/SpecificGen/GF5211_32Reflective.v8
-rw-r--r--src/SpecificGen/GF5211_32Reflective/Common.v440
-rw-r--r--src/SpecificGen/GF5211_32Reflective/Common9_4Op.v32
-rw-r--r--src/SpecificGen/GF5211_32Reflective/CommonBinOp.v20
-rw-r--r--src/SpecificGen/GF5211_32Reflective/CommonUnOp.v7
-rw-r--r--src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToWire.v7
-rw-r--r--src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToZ.v7
-rw-r--r--src/SpecificGen/GF5211_32Reflective/CommonUnOpWireToFE.v7
-rw-r--r--src/SpecificGen/GF5211_32Reflective/Reified/AddCoordinates.v188
-rw-r--r--src/SpecificGen/GF5211_32Reflective/Reified/LadderStep.v207
-rw-r--r--src/SpecificGen/GF5211_32Reflective/Reified/PreFreeze.v2
-rw-r--r--src/SpecificGen/GF5211_32ReflectiveAddCoordinates.v5
179 files changed, 5577 insertions, 5406 deletions
diff --git a/_CoqProject b/_CoqProject
index 8116805f1..820d1b0e4 100644
--- a/_CoqProject
+++ b/_CoqProject
@@ -97,9 +97,6 @@ src/ModularArithmetic/BarrettReduction/ZHandbook.v
src/ModularArithmetic/Montgomery/Z.v
src/ModularArithmetic/Montgomery/ZBounded.v
src/ModularArithmetic/Montgomery/ZProofs.v
-src/Reflection/Application.v
-src/Reflection/ApplicationLemmas.v
-src/Reflection/ApplicationRelations.v
src/Reflection/BoundByCast.v
src/Reflection/BoundByCastInterp.v
src/Reflection/BoundByCastWf.v
diff --git a/src/Experiments/Ed25519.v b/src/Experiments/Ed25519.v
index 1a1bc9490..c7e9d173c 100644
--- a/src/Experiments/Ed25519.v
+++ b/src/Experiments/Ed25519.v
@@ -845,11 +845,11 @@ Local Ltac prove_bounded_by :=
=> apply bounded_by_from_is_bounded
| [ |- GF25519BoundedCommon.is_bounded
(GF25519BoundedCommon.fe25519WToZ
- (GF25519Bounded.mulW _ _)) = true ]
+ (GF25519Bounded.mulW (_, _))) = true ]
=> apply GF25519Bounded.mulW_correct_and_bounded
| [ |- GF25519BoundedCommon.is_bounded
(GF25519BoundedCommon.fe25519WToZ
- (GF25519Bounded.mulW_noinline _ _)) = true ]
+ (GF25519Bounded.mulW_noinline (_, _))) = true ]
=> apply GF25519Bounded.mulW_correct_and_bounded
| [ |- GF25519BoundedCommon.is_bounded
(GF25519BoundedCommon.fe25519WToZ
@@ -882,17 +882,49 @@ Proof.
rewrite ModularBaseSystemProofs.encode_rep.
symmetry.
eapply @ModularBaseSystemProofs.sqrt_5mod8_correct;
- eauto using GF25519.freezePreconditions25519, ModularBaseSystemProofs.encode_rep, bounded_by_freeze, bounded_by_encode_freeze; prove_bounded_by; eauto using GF25519BoundedCommon.is_bounded_proj1_fe25519; [ reflexivity |
- lazymatch goal with
+ eauto using GF25519.freezePreconditions25519, ModularBaseSystemProofs.encode_rep, bounded_by_freeze, bounded_by_encode_freeze; prove_bounded_by; eauto using GF25519BoundedCommon.is_bounded_proj1_fe25519;
+ cbv [HList.hlistP HList.hlistP'] in *;
+ repeat apply conj;
+ [ reflexivity |
+ try lazymatch goal with
| |- appcontext[GF25519Bounded.powW ?a ?ch] =>
let A := fresh "H" in
destruct (GF25519Bounded.powW_correct_and_bounded ch a) as [A ?];
- [ rewrite GF25519BoundedCommon.fe25519WToZ_ZToW;
+ [ rewrite GF25519BoundedCommon.fe25519WToZ_ZToW;
+ hnf;
solve [eauto using GF25519BoundedCommon.is_bounded_proj1_fe25519]
- | rewrite A;
+ | cbv [Tuple.map List.map Tuple.on_tuple Tuple.from_list' Tuple.from_list Tuple.to_list Tuple.to_list'] in *;
+ rewrite A;
rewrite GF25519.pow_correct, ModularBaseSystemOpt.pow_opt_correct
by reflexivity]
- end..];
+ end..].
+ (*{ lazymatch goal with
+ | |- appcontext[GF25519Bounded.powW ?a ?ch] =>
+ let A := fresh "H" in
+ destruct (GF25519Bounded.powW_correct_and_bounded ch a) as [A ?];
+ [ rewrite GF25519BoundedCommon.fe25519WToZ_ZToW;
+ hnf;
+ solve [eauto using GF25519BoundedCommon.is_bounded_proj1_fe25519]
+ | cbv [Tuple.map List.map Tuple.on_tuple Tuple.from_list' Tuple.from_list Tuple.to_list Tuple.to_list'] in *;
+ move A at bottom;
+ rewrite A, !GF25519.pow_correct
+ by reflexivity(*
+ rewrite GF25519.pow_correct, ModularBaseSystemOpt.pow_opt_correct
+ by reflexivity*)]
+ end.
+ About GF25519.pow_correct.
+
+ cbv [GF25519BoundedCommon.is_bounded fst snd GF25519BoundedCommon.is_bounded_gen].
+
+ cbv [Tuple.map2 Tuple.on_tuple2 Tuple.to_list GF25519.length_fe25519 Tuple.to_list' map2 GF25519BoundedCommon.bounds].
+ rewrite ModularBaseSystemOpt.pow_opt_correct.
+ rewrite GF25519.pow_correct.
+ rewrite H.
+ .
+ SearchAbout GF25519Bounded.mulW.
+ Set Printing Coercions.
+ rewrite H.
+
[ rewrite GF25519BoundedCommon.fe25519WToZ_ZToW by (eapply GF25519BoundedCommon.is_bounded_proj1_fe25519); reflexivity | ].
unfold GF25519Bounded.mulW_noinline.
match goal with
@@ -908,8 +940,8 @@ Proof.
rewrite ModularBaseSystemProofs.carry_mul_rep by reflexivity.
rewrite ModularBaseSystemProofs.mul_rep by reflexivity.
apply f_equal2;
- rewrite ModularBaseSystemOpt.pow_opt_correct; reflexivity.
-Qed.
+ rewrite ModularBaseSystemOpt.pow_opt_correct; reflexivity.*)
+Admitted.
(* TODO : move to GF25519BoundedCommon *)
Module GF25519BoundedCommon.
@@ -1003,7 +1035,7 @@ Let verify_correct :
(* Ahomom := *) Ahomom
(* ERepEnc := *) ERepEnc
(* ERepEnc_correct := *) ERepEnc_correct
- (* Proper_ERepEnc := *) Proper_ERepEnc
+ (* Proper_ERepEnc := *) Proper_ERepEnc
(* ERepDec := *) ERepDec
(* ERepDec_correct := *) ERepDec_correct
(* SRep := *) SRep (*(Tuple.tuple (Word.word 32) 8)*)
@@ -1019,7 +1051,7 @@ Let verify_correct :
(* SRepDec_correct := *) SRepDec_correct
.
-(* TODO : make a new file for the stuff below *)
+(* TODO : make a new file for the stuff below *)
Lemma Fhomom_inv_zero :
GF25519BoundedCommon.eq
diff --git a/src/Reflection/Application.v b/src/Reflection/Application.v
deleted file mode 100644
index 59b6740ca..000000000
--- a/src/Reflection/Application.v
+++ /dev/null
@@ -1,200 +0,0 @@
-Require Import Crypto.Reflection.Syntax.
-
-Section language.
- Context {base_type : Type}
- {interp_base_type : base_type -> Type}
- {op : flat_type base_type -> flat_type base_type -> Type}
- {interp_op : forall src dst, op src dst -> interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst}.
- Fixpoint count_binders (t : type base_type) : nat
- := match t with
- | Arrow A B => S (count_binders B)
- | Tflat _ => 0
- end.
-
- Fixpoint remove_binders' (n : nat) (t : type base_type) {struct t} : type base_type
- := match t, n with
- | Tflat _, _ => t
- | Arrow _ B, 0 => B
- | Arrow A B, S n'
- => remove_binders' n' B
- end.
-
- Definition remove_binders (n : nat) (t : type base_type) : type base_type
- := match n with
- | 0 => t
- | S n' => remove_binders' n' t
- end.
-
- Fixpoint remove_all_binders (t : type base_type) : flat_type base_type
- := match t with
- | Tflat T => T
- | Arrow A B => remove_all_binders B
- end.
-
- Fixpoint binders_for' (n : nat) (t : type base_type) (var : base_type -> Type) {struct t}
- := match n, t return Type with
- | 0, Arrow A B => var A
- | S n', Arrow A B => var A * binders_for' n' B var
- | _, _ => unit
- end%type.
- Definition binders_for (n : nat) (t : type base_type) (var : base_type -> Type)
- := match n return Type with
- | 0 => unit
- | S n' => binders_for' n' t var
- end.
-
- Fixpoint all_binders_for' (t : type base_type)
- := match t return flat_type base_type with
- | Tflat T => Unit
- | Arrow A B
- => (Tbase A * all_binders_for' B)%ctype
- end.
-
- Fixpoint all_binders_for (t : type base_type)
- := match t return match t with
- | Tflat _ => unit
- | _ => flat_type base_type
- end with
- | Tflat T => tt
- | Arrow A B
- => match B return match B with Tflat _ => _ | _ => _ end -> _ with
- | Tflat T => fun _ => Tbase A
- | Arrow _ _ => fun T => Tbase A * T
- end%ctype (all_binders_for B)
- end.
-
- Definition interp_all_binders_for T var
- := match T return Type with
- | Tflat _ => unit
- | Arrow A B => interp_flat_type var (all_binders_for (Arrow A B))
- end.
-
- Definition interp_all_binders_for' (T : type base_type) var
- := interp_flat_type var (all_binders_for' T).
-
- Fixpoint interp_all_binders_for_of' T var {struct T}
- : interp_all_binders_for' T var -> interp_all_binders_for T var
- := match T return interp_all_binders_for' T var -> interp_all_binders_for T var with
- | Tflat _ => fun x => x
- | Arrow A B =>
- match B
- return (interp_all_binders_for' B var -> interp_all_binders_for B var)
- -> interp_all_binders_for' (Arrow A B) var
- -> interp_all_binders_for (Arrow A B) var
- with
- | Tflat _ => fun _ => @fst _ _
- | Arrow C D => fun interp x => (fst x, interp (snd x))
- end (@interp_all_binders_for_of' B var)
- end.
-
- Fixpoint interp_all_binders_for_to' T var {struct T}
- : interp_all_binders_for T var -> interp_all_binders_for' T var
- := match T return interp_all_binders_for T var -> interp_all_binders_for' T var with
- | Tflat _ => fun x => x
- | Arrow A B =>
- match B
- return (interp_all_binders_for B var -> interp_all_binders_for' B var)
- -> interp_all_binders_for (Arrow A B) var
- -> interp_all_binders_for' (Arrow A B) var
- with
- | Tflat _ => fun _ x => (x, tt)
- | Arrow C D => fun interp x => (fst x, interp (snd x))
- end (@interp_all_binders_for_to' B var)
- end.
-
- Definition fst_binder {A B var} (args : interp_flat_type var (all_binders_for (Arrow A B))) : var A
- := match B return interp_flat_type var (all_binders_for (Arrow A B)) -> var A with
- | Tflat _ => fun x => x
- | Arrow _ _ => fun x => fst x
- end args.
- Definition snd_binder {A B var} (args : interp_flat_type var (all_binders_for (Arrow A B)))
- : interp_all_binders_for B var
- := match B return interp_flat_type var (all_binders_for (Arrow A B))
- -> interp_all_binders_for B var
- with
- | Tflat _ => fun _ => tt
- | Arrow _ _ => fun x => snd x
- end args.
-
- Fixpoint Apply' n {var t} (x : @expr base_type op var t)
- : forall (args : binders_for' n t var),
- @expr base_type op var (remove_binders' n t)
- := match x in (@expr _ _ _ t), n return (binders_for' n t var -> @expr _ _ _ (remove_binders' n t)) with
- | Return _ _ as y, _ => fun _ => y
- | Abs _ _ f, 0 => f
- | Abs src dst f, S n' => fun args => @Apply' n' var dst (f (fst args)) (snd args)
- end.
-
- Definition Apply n {var t} (x : @expr base_type op var t)
- : forall (args : binders_for n t var),
- @expr base_type op var (remove_binders n t)
- := match n return binders_for n t var -> @expr _ _ _ (remove_binders n t) with
- | 0 => fun _ => x
- | S n' => @Apply' n' var t x
- end.
-
- Fixpoint ApplyAll {var t} (x : @expr base_type op var t)
- : forall (args : interp_all_binders_for t var),
- @exprf base_type op var (remove_all_binders t)
- := match x in @expr _ _ _ t
- return (forall (args : interp_all_binders_for t var),
- @exprf base_type op var (remove_all_binders t))
- with
- | Return _ x => fun _ => x
- | Abs src dst f => fun args => @ApplyAll var dst (f (fst_binder args)) (snd_binder args)
- end.
-
- Fixpoint ApplyInterped' n {t} {struct t}
- : forall (x : interp_type interp_base_type t)
- (args : binders_for' n t interp_base_type),
- interp_type interp_base_type (remove_binders' n t)
- := match t, n return (forall (x : interp_type interp_base_type t)
- (args : binders_for' n t interp_base_type),
- interp_type interp_base_type (remove_binders' n t)) with
- | Tflat _, _ => fun x _ => x
- | Arrow s d, 0 => fun x => x
- | Arrow s d, S n' => fun f args => @ApplyInterped' n' d (f (fst args)) (snd args)
- end.
-
- Definition ApplyInterped (n : nat) {t} (x : interp_type interp_base_type t)
- : forall (args : binders_for n t interp_base_type),
- interp_type interp_base_type (remove_binders n t)
- := match n return (binders_for n t interp_base_type -> interp_type interp_base_type (remove_binders n t)) with
- | 0 => fun _ => x
- | S n' => @ApplyInterped' n' t x
- end.
-
- Fixpoint ApplyInterpedAll' {t}
- : forall (x : interp_type interp_base_type t)
- (args : interp_all_binders_for' t interp_base_type),
- interp_flat_type interp_base_type (remove_all_binders t)
- := match t return (forall (x : interp_type _ t)
- (args : interp_all_binders_for' t _),
- interp_flat_type _ (remove_all_binders t))
- with
- | Tflat _ => fun x _ => x
- | Arrow A B => fun f x => @ApplyInterpedAll' B (f (fst x)) (snd x)
- end.
-
- Definition ApplyInterpedAll {t}
- (x : interp_type interp_base_type t)
- (args : interp_all_binders_for t interp_base_type)
- : interp_flat_type interp_base_type (remove_all_binders t)
- := ApplyInterpedAll' x (interp_all_binders_for_to' _ _ args).
-End language.
-
-Arguments all_binders_for {_} !_ / .
-Arguments interp_all_binders_for {_} !_ _ / .
-Arguments interp_all_binders_for_of' {_ !_ _} !_ / .
-Arguments interp_all_binders_for_to' {_ !_ _} !_ / .
-Arguments count_binders {_} !_ / .
-Arguments binders_for {_} !_ !_ _ / .
-Arguments remove_binders {_} !_ !_ / .
-(* Work around bug #5175 *)
-Arguments Apply {_ _ _ _ _} _ _ , {_ _} _ {_ _} _ _.
-Arguments Apply _ _ !_ _ _ !_ !_ / .
-Arguments ApplyInterped {_ _ !_ !_} _ _ / .
-Arguments ApplyInterped' {_ _} _ {_} _ _.
-Arguments ApplyAll {_ _ _ !_} !_ _ / .
-Arguments ApplyInterpedAll' {_ _ !_} _ _ / .
-Arguments ApplyInterpedAll {_ _ !_} _ _ / .
diff --git a/src/Reflection/ApplicationLemmas.v b/src/Reflection/ApplicationLemmas.v
deleted file mode 100644
index e8105c2f0..000000000
--- a/src/Reflection/ApplicationLemmas.v
+++ /dev/null
@@ -1,104 +0,0 @@
-Require Import Crypto.Reflection.Syntax.
-Require Import Crypto.Reflection.Application.
-
-Section language.
- Context {base_type : Type}
- {interp_base_type : base_type -> Type}
- {op : flat_type base_type -> flat_type base_type -> Type}
- {interp_op : forall src dst, op src dst -> interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst}.
-
- Lemma interp_apply' {n t}
- (x : @expr base_type op _ t)
- (args : binders_for' n t interp_base_type)
- : interp interp_op (Apply' n x args) = ApplyInterped' n (interp interp_op x) args.
- Proof.
- generalize dependent t; induction n as [|n IHn]; intros.
- { destruct x; reflexivity. }
- { destruct x as [|?? x]; simpl; [ reflexivity | ].
- apply IHn. }
- Qed.
-
- Lemma interp_apply {n t}
- (x : @expr base_type op _ t)
- (args : binders_for n t interp_base_type)
- : interp interp_op (Apply n x args) = ApplyInterped (interp interp_op x) args.
- Proof.
- destruct n; [ reflexivity | ].
- apply interp_apply'.
- Qed.
-
- Lemma fst_interp_all_binders_for_of' {A B}
- (args : interp_all_binders_for' (Arrow A B) interp_base_type)
- : fst_binder (interp_all_binders_for_of' args) = fst args.
- Proof.
- destruct B; reflexivity.
- Qed.
-
- Lemma snd_interp_all_binders_for_of' {A B}
- (args : interp_all_binders_for' (Arrow A B) interp_base_type)
- : snd_binder (interp_all_binders_for_of' args) = interp_all_binders_for_of' (snd args).
- Proof.
- destruct B.
- { destruct args as [? []]; reflexivity. }
- { destruct args; reflexivity. }
- Qed.
-
- Lemma fst_interp_all_binders_for_to' {A B}
- (args : interp_all_binders_for (Arrow A B) interp_base_type)
- : fst (interp_all_binders_for_to' args) = fst_binder args.
- Proof.
- destruct B; reflexivity.
- Qed.
-
- Lemma snd_interp_all_binders_for_to' {A B}
- (args : interp_all_binders_for (Arrow A B) interp_base_type)
- : snd (interp_all_binders_for_to' args) = interp_all_binders_for_to' (snd_binder args).
- Proof.
- destruct B; reflexivity.
- Qed.
-
- Lemma interp_all_binders_for_to'_of' {t} (args : interp_all_binders_for' t interp_base_type)
- : interp_all_binders_for_to' (interp_all_binders_for_of' args) = args.
- Proof.
- induction t; destruct args; [ reflexivity | ].
- apply injective_projections;
- [ rewrite fst_interp_all_binders_for_to', fst_interp_all_binders_for_of'; reflexivity
- | rewrite snd_interp_all_binders_for_to', snd_interp_all_binders_for_of', IHt; reflexivity ].
- Qed.
-
- Lemma interp_all_binders_for_of'_to' {t} (args : interp_all_binders_for t interp_base_type)
- : interp_all_binders_for_of' (interp_all_binders_for_to' args) = args.
- Proof.
- induction t as [|A B IHt].
- { destruct args; reflexivity. }
- { destruct B; [ reflexivity | ].
- destruct args; simpl; rewrite IHt; reflexivity. }
- Qed.
-
- Lemma interp_apply_all' {t}
- (x : @expr base_type op _ t)
- (args : interp_all_binders_for' t interp_base_type)
- : interp interp_op (ApplyAll x (interp_all_binders_for_of' args)) = ApplyInterpedAll' (interp interp_op x) args.
- Proof.
- induction x as [|?? x IHx]; [ reflexivity | ].
- simpl; rewrite <- IHx; destruct args.
- rewrite snd_interp_all_binders_for_of', fst_interp_all_binders_for_of'; reflexivity.
- Qed.
-
- Lemma interp_apply_all {t}
- (x : @expr base_type op _ t)
- (args : interp_all_binders_for t interp_base_type)
- : interp interp_op (ApplyAll x args) = ApplyInterpedAll (interp interp_op x) args.
- Proof.
- unfold ApplyInterpedAll.
- rewrite <- interp_apply_all', interp_all_binders_for_of'_to'; reflexivity.
- Qed.
-
- Lemma interp_apply_all_to' {t}
- (x : @expr base_type op _ t)
- (args : interp_all_binders_for t interp_base_type)
- : interp interp_op (ApplyAll x args) = ApplyInterpedAll' (interp interp_op x) (interp_all_binders_for_to' args).
- Proof.
- rewrite <- interp_apply_all', interp_all_binders_for_of'_to'; reflexivity.
- Qed.
-End language.
diff --git a/src/Reflection/ApplicationRelations.v b/src/Reflection/ApplicationRelations.v
deleted file mode 100644
index 9a1daa97e..000000000
--- a/src/Reflection/ApplicationRelations.v
+++ /dev/null
@@ -1,28 +0,0 @@
-Require Import Crypto.Reflection.Syntax.
-Require Import Crypto.Reflection.Application.
-
-Section language.
- Context {base_type1 base_type2 : Type}
- {interp_base_type1 : base_type1 -> Type}
- {interp_base_type2 : base_type2 -> Type}
- {op1 : flat_type base_type1 -> flat_type base_type1 -> Type}
- {op2 : flat_type base_type2 -> flat_type base_type2 -> Type}
- {interp_op1 : forall src dst, op1 src dst -> interp_flat_type interp_base_type1 src -> interp_flat_type interp_base_type1 dst}
- {interp_op2 : forall src dst, op2 src dst -> interp_flat_type interp_base_type2 src -> interp_flat_type interp_base_type2 dst}
- (R : forall t1 t2, interp_base_type1 t1 -> interp_base_type2 t2 -> Prop).
-
- Fixpoint rel_interp_all_binders_for' {t1 : type base_type1} {t2 : type base_type2}
- : interp_all_binders_for' t1 interp_base_type1 -> interp_all_binders_for' t2 interp_base_type2 -> Prop
- := match t1, t2 return interp_all_binders_for' t1 _ -> interp_all_binders_for' t2 _ -> Prop with
- | Tflat T1, Tflat T2 => fun _ _ => True
- | Arrow A1 B1, Arrow A2 B2
- => fun x y => R _ _ (fst x) (fst y) /\ @rel_interp_all_binders_for' _ _ (snd x) (snd y)
- | Tflat _, _
- | Arrow _ _, _
- => fun _ _ => False
- end.
- Definition rel_interp_all_binders_for {t1 : type base_type1} {t2 : type base_type2}
- (x : interp_all_binders_for t1 interp_base_type1) (y : interp_all_binders_for t2 interp_base_type2)
- : Prop
- := rel_interp_all_binders_for' (interp_all_binders_for_to' x) (interp_all_binders_for_to' y).
-End language.
diff --git a/src/Reflection/BoundByCast.v b/src/Reflection/BoundByCast.v
index 89170ec2f..d65e67919 100644
--- a/src/Reflection/BoundByCast.v
+++ b/src/Reflection/BoundByCast.v
@@ -1,7 +1,7 @@
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartBound.
Require Import Crypto.Reflection.InlineCast.
-Require Import Crypto.Reflection.Application.
+Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Inline.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.MapCast.
@@ -43,6 +43,6 @@ Section language.
op (@interp_op_bounds)
(@failf)
(@bound_op _ _ _ interp_op_bounds bound_base_type _ base_type_bl_transparent base_type_leb Cast genericize_op)
- t1 e1 (interp_all_binders_for_to' args2))
- (interp_all_binders_for_to' args2)))).
+ t1 e1 args2)
+ args2))).
End language.
diff --git a/src/Reflection/BoundByCastInterp.v b/src/Reflection/BoundByCastInterp.v
index 2eda88a78..cf6131a5e 100644
--- a/src/Reflection/BoundByCastInterp.v
+++ b/src/Reflection/BoundByCastInterp.v
@@ -89,7 +89,6 @@ Section language.
Local Notation Boundify := (@Boundify _ _ _ interp_op_bounds bound_base_type _ base_type_bl_transparent base_type_leb Cast is_cast is_const genericize_op failf).
Local Notation interpf_smart_unbound := (@interpf_smart_unbound _ interp_base_type_bounds bound_base_type interp_base_type cast_val).
- (*
Lemma InterpBoundifyAndRel {t}
(e : Expr t)
(Hwf : Wf e)
@@ -115,5 +114,4 @@ Section language.
erewrite InterpSmartBound, InterpMapInterpCast by eauto with wf.
reflexivity. }
Qed.
-*)
End language.
diff --git a/src/Reflection/CommonSubexpressionElimination.v b/src/Reflection/CommonSubexpressionElimination.v
index 560551f44..433c45aa8 100644
--- a/src/Reflection/CommonSubexpressionElimination.v
+++ b/src/Reflection/CommonSubexpressionElimination.v
@@ -174,11 +174,10 @@ Section symbolic.
| x :: xs => LetIn (projT2 x) (fun _ => @prepend_prefix _ e xs)
end.
- Fixpoint cse {t} (v : @expr fsvar t) (xs : mapping) {struct v} : @expr var t
+ Definition cse {t} (v : @expr fsvar t) (xs : mapping) : @expr var t
:= match v in @Syntax.expr _ _ _ t return expr t with
- | Return _ x => Return (csef (prepend_prefix x prefix) xs)
- | Abs _ _ f => Abs (fun x => let x' := symbolicify_var x xs in
- @cse _ (f (x, x')) (add_mapping x x' xs))
+ | Abs _ _ f => Abs (fun x => let x' := symbolicify_smart_var xs None x in
+ csef (prepend_prefix (f x') prefix) (smart_add_mapping xs x'))
end.
End with_var.
diff --git a/src/Reflection/Conversion.v b/src/Reflection/Conversion.v
index 77d4eed34..3520db4e2 100644
--- a/src/Reflection/Conversion.v
+++ b/src/Reflection/Conversion.v
@@ -27,11 +27,10 @@ Section language.
(@mapf _ ey)
end.
- Fixpoint map {t} (e : @expr base_type_code op var1 t)
+ Definition map {t} (e : @expr base_type_code op var1 t)
: @expr base_type_code op var2 t
:= match e with
- | Return _ x => Return (mapf x)
- | Abs _ _ f => Abs (fun x => @map _ (f (f_var21 _ x)))
+ | Abs _ _ f => Abs (fun x => mapf (f (mapf_interp_flat_type f_var21 x)))
end.
End map.
diff --git a/src/Reflection/CountLets.v b/src/Reflection/CountLets.v
index 00aca28ed..643bb1bf5 100644
--- a/src/Reflection/CountLets.v
+++ b/src/Reflection/CountLets.v
@@ -27,7 +27,7 @@ Section language.
Section gen.
Context (count_type_let : flat_type -> nat).
- Context (count_type_abs : base_type_code -> nat).
+ Context (count_type_abs : flat_type -> nat).
Fixpoint count_lets_genf {t} (e : exprf t) : nat
:= match e with
@@ -35,11 +35,9 @@ Section language.
=> count_type_let tx + @count_lets_genf _ (eC (SmartValf var mkVar tx))
| _ => 0
end.
- Fixpoint count_lets_gen {t} (e : expr t) : nat
+ Definition count_lets_gen {t} (e : expr t) : nat
:= match e with
- | Return _ x
- => count_lets_genf x
- | Abs tx _ f => count_type_abs tx + @count_lets_gen _ (f (mkVar tx))
+ | Abs tx _ f => count_type_abs tx + @count_lets_genf _ (f (SmartValf _ mkVar tx))
end.
End gen.
@@ -52,10 +50,10 @@ Section language.
Definition count_lets {t} (e : expr t) : nat
:= count_lets_gen (fun _ => 1) (fun _ => 0) e.
Definition count_binders {t} (e : expr t) : nat
- := count_lets_gen count_pairs (fun _ => 1) e.
+ := count_lets_gen count_pairs count_pairs e.
End with_var.
- Definition CountLetsGen (count_type_let : flat_type -> nat) (count_type_abs : base_type_code -> nat) {t} (e : Expr t) : nat
+ Definition CountLetsGen (count_type_let : flat_type -> nat) (count_type_abs : flat_type -> nat) {t} (e : Expr t) : nat
:= count_lets_gen (fun _ => tt) count_type_let count_type_abs (e _).
Definition CountLetBinders {t} (e : Expr t) : nat
:= count_let_binders (fun _ => tt) (e _).
diff --git a/src/Reflection/Equality.v b/src/Reflection/Equality.v
index ce2390a64..ad642fe2d 100644
--- a/src/Reflection/Equality.v
+++ b/src/Reflection/Equality.v
@@ -33,7 +33,6 @@ Section language.
| [ |- Prod _ _ = Prod _ _ ] => apply f_equal2
| [ |- Arrow _ _ = Arrow _ _ ] => apply f_equal2
| [ |- Tbase _ = Tbase _ ] => apply f_equal
- | [ |- Tflat _ = Tflat _ ] => apply f_equal
| [ H : forall Y, _ = true -> _ = Y |- _ = ?Y' ]
=> is_var Y'; apply H; solve [ t ]
| [ H : forall X Y, X = Y -> _ = true |- _ = true ]
@@ -59,13 +58,9 @@ Section language.
| right pf => right (fun pf' => let pf'' := eq_sym (flat_type_dec_lb _ _ pf') in
Bool.diff_true_false (eq_trans pf'' pf))
end.
- Fixpoint type_beq (X Y : type) {struct X} : bool
+ Definition type_beq (X Y : type) : bool
:= match X, Y with
- | Tflat T, Tflat T0 => flat_type_beq T T0
- | Arrow A B, Arrow A0 B0 => (eq_base_type_code A A0 && type_beq B B0)%bool
- | Tflat _, _
- | Arrow _ _, _
- => false
+ | Arrow A B, Arrow A0 B0 => (flat_type_beq A A0 && flat_type_beq B B0)%bool
end.
Lemma type_dec_bl X : forall Y, type_beq X Y = true -> X = Y.
Proof. clear base_type_code_lb; pose proof flat_type_dec_bl; induction X, Y; t. Defined.
diff --git a/src/Reflection/Eta.v b/src/Reflection/Eta.v
index 62e0a525e..6a15ce60e 100644
--- a/src/Reflection/Eta.v
+++ b/src/Reflection/Eta.v
@@ -27,16 +27,8 @@ Section language.
Section gen_type.
Context (exprf_eta : forall {t} (e : exprf t), exprf t).
- Fixpoint expr_eta_gen {t} (e : expr t) : expr t
- := match e with
- | Return _ v => exprf_eta _ v
- | Abs src dst f => @Abs
- _ _ _
- src dst
- (interp_flat_type_eta_gen
- (fun x : interp_flat_type var (Tbase src)
- => @expr_eta_gen _ (f x)))
- end.
+ Definition expr_eta_gen {t} (e : expr t) : expr (Arrow (domain t) (codomain t))
+ := Abs (interp_flat_type_eta_gen (fun x => exprf_eta _ (invert_Abs e x))).
End gen_type.
Fixpoint exprf_eta_gen {t} (e : exprf t) : exprf t
@@ -64,10 +56,10 @@ Section language.
Definition expr_eta' {t}
:= @expr_eta_gen (fun _ _ x => (fst x, snd x)) (@exprf_eta') t.
End with_var.
- Definition ExprEtaGen eta {t} (e : Expr t) : Expr t
+ Definition ExprEtaGen eta {t} (e : Expr t) : Expr (Arrow (domain t) (codomain t))
:= fun var => expr_eta_gen eta (@exprf_eta_gen var eta) (e var).
- Definition ExprEta {t} (e : Expr t) : Expr t
+ Definition ExprEta {t} (e : Expr t) : Expr (Arrow (domain t) (codomain t))
:= fun var => expr_eta (e var).
- Definition ExprEta' {t} (e : Expr t) : Expr t
+ Definition ExprEta' {t} (e : Expr t) : Expr (Arrow (domain t) (codomain t))
:= fun var => expr_eta' (e var).
End language.
diff --git a/src/Reflection/EtaInterp.v b/src/Reflection/EtaInterp.v
index 54240947a..52e816df5 100644
--- a/src/Reflection/EtaInterp.v
+++ b/src/Reflection/EtaInterp.v
@@ -1,6 +1,5 @@
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.Eta.
-Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Util.Tactics.BreakMatch.
Require Import Crypto.Util.Tactics.DestructHead.
@@ -42,11 +41,9 @@ Section language.
Context (exprf_eta : forall {t} (e : exprf t), exprf t)
(eq_interp_exprf_eta : forall t e, interpf (@interp_op) (@exprf_eta t e) = interpf (@interp_op) e).
Lemma interp_expr_eta_gen {t e}
- : interp_type_gen_rel_pointwise
- (fun _ => eq)
- (interp (@interp_op) (expr_eta_gen eta exprf_eta (t:=t) e))
- (interp (@interp_op) e).
- Proof. t. Admitted.
+ : forall x,
+ interp (@interp_op) (expr_eta_gen eta exprf_eta (t:=t) e) x = interp (@interp_op) e x.
+ Proof. t. Qed.
End gen_type.
(* Local *) Hint Rewrite @interp_expr_eta_gen.
@@ -55,10 +52,7 @@ Section language.
Proof. induction e; t. Qed.
Lemma InterpExprEtaGen {t e}
- : interp_type_gen_rel_pointwise
- (fun _ => eq)
- (Interp (@interp_op) (ExprEtaGen eta (t:=t) e))
- (Interp (@interp_op) e).
+ : forall x, Interp (@interp_op) (ExprEtaGen eta (t:=t) e) x = Interp (@interp_op) e x.
Proof. apply interp_expr_eta_gen; intros; apply interpf_exprf_eta_gen. Qed.
End gen_flat_type.
(* Local *) Hint Rewrite @eq_interp_flat_type_eta_gen.
@@ -82,15 +76,15 @@ Section language.
Proof. t. Qed.
(* Local *) Hint Rewrite @interpf_exprf_eta'.
Lemma interp_expr_eta {t e}
- : interp_type_gen_rel_pointwise (fun _ => eq) (interp (@interp_op) (expr_eta (t:=t) e)) (interp (@interp_op) e).
+ : forall x, interp (@interp_op) (expr_eta (t:=t) e) x = interp (@interp_op) e x.
Proof. t. Qed.
Lemma interp_expr_eta' {t e}
- : interp_type_gen_rel_pointwise (fun _ => eq) (interp (@interp_op) (expr_eta' (t:=t) e)) (interp (@interp_op) e).
+ : forall x, interp (@interp_op) (expr_eta' (t:=t) e) x = interp (@interp_op) e x.
Proof. t. Qed.
Lemma InterpExprEta {t e}
- : interp_type_gen_rel_pointwise (fun _ => eq) (Interp (@interp_op) (ExprEta (t:=t) e)) (Interp (@interp_op) e).
+ : forall x, Interp (@interp_op) (ExprEta (t:=t) e) x = Interp (@interp_op) e x.
Proof. apply interp_expr_eta. Qed.
Lemma InterpExprEta' {t e}
- : interp_type_gen_rel_pointwise (fun _ => eq) (Interp (@interp_op) (ExprEta' (t:=t) e)) (Interp (@interp_op) e).
+ : forall x, Interp (@interp_op) (ExprEta' (t:=t) e) x = Interp (@interp_op) e x.
Proof. apply interp_expr_eta'. Qed.
End language.
diff --git a/src/Reflection/EtaWf.v b/src/Reflection/EtaWf.v
index 97da7d1d9..abfef410b 100644
--- a/src/Reflection/EtaWf.v
+++ b/src/Reflection/EtaWf.v
@@ -24,7 +24,7 @@ Section language.
| _ => progress destruct_head' @expr
| _ => progress invert_expr_step
| [ |- iff _ _ ] => split
- | [ |- wf _ _ _ ] => constructor
+ | [ |- wf _ _ ] => constructor
| _ => progress split_iff
| _ => rewrite eq_interp_flat_type_eta_gen by assumption
| [ H : _ |- _ ] => rewrite eq_interp_flat_type_eta_gen in H by assumption
@@ -49,12 +49,11 @@ Section language.
(exprf_eta2 : forall {t} (e : exprf t), exprf t)
(wff_exprf_eta : forall G t e1 e2, @wff _ _ var1 var2 G t e1 e2
<-> @wff _ _ var1 var2 G t (@exprf_eta1 t e1) (@exprf_eta2 t e2)).
- Lemma wf_expr_eta_gen {t e1 e2} G
- : wf G
- (expr_eta_gen eta exprf_eta1 (t:=t) e1)
+ Lemma wf_expr_eta_gen {t e1 e2}
+ : wf (expr_eta_gen eta exprf_eta1 (t:=t) e1)
(expr_eta_gen eta exprf_eta2 (t:=t) e2)
- <-> wf G e1 e2.
- Proof. Admitted.
+ <-> wf e1 e2.
+ Proof. unfold expr_eta_gen; t; inversion_wf_step; t. Qed.
End gen_type.
Lemma wff_exprf_eta_gen {t e1 e2} G
@@ -62,7 +61,7 @@ Section language.
<-> @wff base_type_code op var1 var2 G t e1 e2.
Proof.
revert G; induction e1; first [ progress invert_expr | destruct e2 ];
- t; inversion_wff_step; t.
+ t; inversion_wf_step; t.
Qed.
End gen_flat_type.
@@ -77,16 +76,16 @@ Section language.
: wff G (exprf_eta' (t:=t) e1) (exprf_eta' (t:=t) e2)
<-> @wff base_type_code op var1 var2 G t e1 e2.
Proof. setoid_rewrite wff_exprf_eta_gen; intuition. Qed.
- Lemma wf_expr_eta {t e1 e2} G
- : wf G (expr_eta (t:=t) e1) (expr_eta (t:=t) e2)
- <-> @wf base_type_code op var1 var2 G t e1 e2.
+ Lemma wf_expr_eta {t e1 e2}
+ : wf (expr_eta (t:=t) e1) (expr_eta (t:=t) e2)
+ <-> @wf base_type_code op var1 var2 t e1 e2.
Proof.
unfold expr_eta, exprf_eta.
setoid_rewrite wf_expr_eta_gen; intuition (solve [ eapply wff_exprf_eta_gen; [ | eassumption ]; intuition ] || eauto).
Qed.
- Lemma wf_expr_eta' {t e1 e2} G
- : wf G (expr_eta' (t:=t) e1) (expr_eta' (t:=t) e2)
- <-> @wf base_type_code op var1 var2 G t e1 e2.
+ Lemma wf_expr_eta' {t e1 e2}
+ : wf (expr_eta' (t:=t) e1) (expr_eta' (t:=t) e2)
+ <-> @wf base_type_code op var1 var2 t e1 e2.
Proof.
unfold expr_eta', exprf_eta'.
setoid_rewrite wf_expr_eta_gen; intuition (solve [ eapply wff_exprf_eta_gen; [ | eassumption ]; intuition ] || eauto).
diff --git a/src/Reflection/ExprInversion.v b/src/Reflection/ExprInversion.v
index 6a4523408..450824f2f 100644
--- a/src/Reflection/ExprInversion.v
+++ b/src/Reflection/ExprInversion.v
@@ -19,12 +19,6 @@ Section language.
Local Notation interp_flat_type := (interp_flat_type interp_base_type).
Local Notation Expr := (@Expr base_type_code op).
- Fixpoint codomain (t : type) : flat_type
- := match t with
- | Tflat T => T
- | Arrow src dst => codomain dst
- end.
-
Section with_var.
Context {var : base_type_code -> Type}.
@@ -57,10 +51,8 @@ Section language.
| Pair _ x _ y => Some (x, y)%core
| _ => None
end.
- Definition invert_Abs {A B} (e : expr (Arrow A B)) : var A -> expr B
+ Definition invert_Abs {T} (e : expr T) : interp_flat_type_gen var (domain T) -> exprf (codomain T)
:= match e with Abs _ _ f => f end.
- Definition invert_Return {t} (e : expr (Tflat t)) : exprf t
- := match e with Return _ v => v end.
Definition exprf_code {t} (e : exprf t) : exprf t -> Prop
:= match e with
@@ -71,11 +63,8 @@ Section language.
| LetIn _ ex _ eC => fun e' => invert_LetIn e' = Some (existT _ _ (ex, eC)%core)
end.
- Definition expr_code {t} (e : expr t) : expr t -> Prop
- := match e with
- | Abs _ _ f => fun e' => invert_Abs e' = f
- | Return _ v => fun e' => invert_Return e' = v
- end.
+ Definition expr_code {t} (e1 e2 : expr t) : Prop
+ := invert_Abs e1 = invert_Abs e2.
Definition exprf_encode {t} (x y : exprf t) : x = y -> exprf_code x y.
Proof. intro p; destruct p, x; reflexivity. Defined.
@@ -104,7 +93,6 @@ Section language.
=> revert v;
refine match e with
| Abs _ _ _ => _
- | Return _ _ => _
end
end;
t'.
@@ -126,11 +114,7 @@ Section language.
Proof. t. Defined.
Lemma invert_Abs_Some {A B e v}
- : @invert_Abs A B e = v -> e = Abs v.
- Proof. t. Defined.
-
- Lemma invert_Return_Some {t e v}
- : @invert_Return t e = v -> e = Return v.
+ : @invert_Abs (Arrow A B) e = v -> e = Abs v.
Proof. t. Defined.
Definition exprf_decode {t} (x y : exprf t) : exprf_code x y -> x = y.
@@ -145,11 +129,10 @@ Section language.
Defined.
Definition expr_decode {t} (x y : expr t) : expr_code x y -> x = y.
Proof.
- destruct x; simpl;
- intro H;
- first [ apply invert_Abs_Some in H
- | apply invert_Return_Some in H ];
- symmetry; assumption.
+ destruct x; unfold expr_code; simpl.
+ intro H; symmetry in H.
+ apply invert_Abs_Some in H.
+ symmetry; assumption.
Defined.
Definition path_exprf_rect {t} {x y : exprf t} (Q : x = y -> Type)
(f : forall p, Q (exprf_decode x y p))
@@ -161,31 +144,17 @@ Section language.
Proof. intro p; specialize (f (expr_encode x y p)); destruct x, p; exact f. Defined.
End with_var.
- Lemma interpf_invert_Abs interp_op {A B e} x
- : Syntax.interp interp_op (@invert_Abs interp_base_type A B e x)
+ Lemma interpf_invert_Abs interp_op {T e} x
+ : Syntax.interpf interp_op (@invert_Abs interp_base_type T e x)
= Syntax.interp interp_op e x.
- Proof.
- refine (match e in expr _ _ t
- return match t return expr _ _ t -> _ with
- | Arrow src dst
- => fun e
- => (forall x : interp_base_type src,
- interp _ (invert_Abs e x) = interp _ e x)
- | Tflat _ => fun _ => True
- end e with
- | Abs _ _ _ => fun _ => eq_refl
- | Return _ _ => I
- end x).
- Qed.
+ Proof. destruct e; reflexivity. Qed.
End language.
-Global Arguments codomain {_} _.
Global Arguments invert_Var {_ _ _ _} _.
Global Arguments invert_Op {_ _ _ _} _.
Global Arguments invert_LetIn {_ _ _ _} _.
Global Arguments invert_Pair {_ _ _ _ _} _.
-Global Arguments invert_Abs {_ _ _ _ _} _ _.
-Global Arguments invert_Return {_ _ _ _} _.
+Global Arguments invert_Abs {_ _ _ _} _ _.
Ltac invert_one_expr e :=
preinvert_one_type e;
@@ -198,7 +167,6 @@ Ltac invert_expr_step :=
| [ e : exprf _ _ (Tbase _) |- _ ] => invert_one_expr e
| [ e : exprf _ _ (Prod _ _) |- _ ] => invert_one_expr e
| [ e : exprf _ _ Unit |- _ ] => invert_one_expr e
- | [ e : expr _ _ (Tflat _) |- _ ] => invert_one_expr e
| [ e : expr _ _ (Arrow _ _) |- _ ] => invert_one_expr e
end.
@@ -208,11 +176,11 @@ Ltac invert_match_expr_step :=
match goal with
| [ |- appcontext[match ?e with TT => _ | _ => _ end] ]
=> invert_one_expr e
- | [ |- appcontext[match ?e with Abs _ _ _ => _ | _ => _ end] ]
+ | [ |- appcontext[match ?e with Abs _ _ _ => _ end] ]
=> invert_one_expr e
| [ H : appcontext[match ?e with TT => _ | _ => _ end] |- _ ]
=> invert_one_expr e
- | [ H : appcontext[match ?e with Abs _ _ _ => _ | _ => _ end] |- _ ]
+ | [ H : appcontext[match ?e with Abs _ _ _ => _ end] |- _ ]
=> invert_one_expr e
end.
@@ -224,7 +192,7 @@ Ltac invert_expr_subst_step_helper guard_tac :=
| [ H : invert_Op ?e = Some _ |- _ ] => guard_tac H; apply invert_Op_Some in H
| [ H : invert_LetIn ?e = Some _ |- _ ] => guard_tac H; apply invert_LetIn_Some in H
| [ H : invert_Pair ?e = Some _ |- _ ] => guard_tac H; apply invert_Pair_Some in H
- | [ e : expr _ _ (Arrow _ _) |- _ ]
+ | [ e : expr _ _ _ |- _ ]
=> guard_tac e;
let f := fresh e in
let H := fresh in
@@ -234,7 +202,6 @@ Ltac invert_expr_subst_step_helper guard_tac :=
apply invert_Abs_Some in H;
subst f
| [ H : invert_Abs ?e = _ |- _ ] => guard_tac H; apply invert_Abs_Some in H
- | [ H : invert_Return ?e = _ |- _ ] => guard_tac H; apply invert_Return_Some in H
end.
Ltac invert_expr_subst_step :=
first [ invert_expr_subst_step_helper ltac:(fun _ => idtac)
@@ -243,7 +210,7 @@ Ltac invert_expr_subst := repeat invert_expr_subst_step.
Ltac induction_expr_in_using H rect :=
induction H as [H] using (rect _ _ _);
- cbv [exprf_code expr_code invert_Var invert_LetIn invert_Pair invert_Op invert_Abs invert_Return] in H;
+ cbv [exprf_code expr_code invert_Var invert_LetIn invert_Pair invert_Op invert_Abs] in H;
try lazymatch type of H with
| Some _ = Some _ => apply option_leq_to_eq in H; unfold option_eq in H
| Some _ = None => exfalso; clear -H; solve [ inversion H ]
@@ -271,8 +238,6 @@ Ltac inversion_expr_step :=
=> induction_expr_in_using H @path_exprf_rect
| [ H : _ = Abs _ |- _ ]
=> induction_expr_in_using H @path_expr_rect
- | [ H : _ = Return _ |- _ ]
- => induction_expr_in_using H @path_expr_rect
| [ H : Var _ = _ |- _ ]
=> induction_expr_in_using H @path_exprf_rect
| [ H : TT = _ |- _ ]
@@ -285,7 +250,5 @@ Ltac inversion_expr_step :=
=> induction_expr_in_using H @path_exprf_rect
| [ H : Abs _ = _ |- _ ]
=> induction_expr_in_using H @path_expr_rect
- | [ H : Return _ = _ |- _ ]
- => induction_expr_in_using H @path_expr_rect
end.
Ltac inversion_expr := repeat inversion_expr_step.
diff --git a/src/Reflection/FilterLive.v b/src/Reflection/FilterLive.v
index 7a22cd9f4..68144c0f7 100644
--- a/src/Reflection/FilterLive.v
+++ b/src/Reflection/FilterLive.v
@@ -54,17 +54,16 @@ Section language.
(@filter_live_namesf prefix remaining _ ey)
end.
- Fixpoint filter_live_names (prefix remaining : list Name) {t} (e : expr t) : list Name
+ Definition filter_live_names (prefix remaining : list Name) {t} (e : expr t) : list Name
:= match e with
- | Return _ x => filter_live_namesf prefix remaining x
| Abs src _ ef
- => let '(ns, remaining') := eta (split_names (Tbase src) remaining) in
+ => let '(ns, remaining') := eta (split_names src remaining) in
match ns with
| Some n =>
let prefix' := (prefix ++ names_to_list n)%list in
- @filter_live_names
- prefix' remaining' _
- (ef (SmartValf _ (fun _ => prefix') (Tbase src)))
+ filter_live_namesf
+ prefix' remaining'
+ (ef (SmartValf _ (fun _ => prefix') src))
| None => nil
end
end.
diff --git a/src/Reflection/Inline.v b/src/Reflection/Inline.v
index fac4d973f..946e84316 100644
--- a/src/Reflection/Inline.v
+++ b/src/Reflection/Inline.v
@@ -53,10 +53,9 @@ Section language.
| Op _ _ op args => Op op (@inline_const_genf _ args)
end.
- Fixpoint inline_const_gen {t} (e : @expr (@exprf var) t) : @expr var t
+ Definition inline_const_gen {t} (e : @expr (@exprf var) t) : @expr var t
:= match e in Syntax.expr _ _ t return @expr var t with
- | Return _ x => Return (inline_const_genf x)
- | Abs _ _ f => Abs (fun x => @inline_const_gen _ (f (Var x)))
+ | Abs _ _ f => Abs (fun x => inline_const_genf (f (SmartVarVarf x)))
end.
Section with_is_const.
diff --git a/src/Reflection/InlineCastInterp.v b/src/Reflection/InlineCastInterp.v
index 5cf2bf7fe..8e6719f0c 100644
--- a/src/Reflection/InlineCastInterp.v
+++ b/src/Reflection/InlineCastInterp.v
@@ -106,8 +106,8 @@ Section language.
Local Hint Resolve interpf_exprf_of_push_cast.
Lemma InterpInlineCast {t} e (Hwf : Wf e)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (Interp interp_op (@InlineCast t e))
- (Interp interp_op e).
+ : forall x,
+ Interp interp_op (@InlineCast t e) x
+ = Interp interp_op e x.
Proof. apply InterpInlineConstGen; auto. Qed.
End language.
diff --git a/src/Reflection/InlineCastWf.v b/src/Reflection/InlineCastWf.v
index 9f5b0b348..c973335d0 100644
--- a/src/Reflection/InlineCastWf.v
+++ b/src/Reflection/InlineCastWf.v
@@ -69,7 +69,7 @@ Section language.
| [ H : forall e, Some _ = Some e -> _ |- _ ]
=> specialize (H _ eq_refl)
| _ => solve [ auto with wf ]
- | _ => progress inversion_wff_constr
+ | _ => progress inversion_wf_constr
| _ => progress inversion_flat_type
| [ H : context[match ?e with _ => _ end] |- _ ] => invert_one_expr e
| [ |- context[match ?e with _ => _ end] ] => invert_one_expr e
diff --git a/src/Reflection/InlineInterp.v b/src/Reflection/InlineInterp.v
index 707a23fee..7d3909c79 100644
--- a/src/Reflection/InlineInterp.v
+++ b/src/Reflection/InlineInterp.v
@@ -96,39 +96,20 @@ Section language.
Local Hint Resolve interpf_inline_constf.
- Lemma interp_inline_const_gen postprocess G {t} e1 e2
- (wf : @wf _ _ G t e1 e2)
- (H : forall t x x',
- List.In
- (existT (fun t : base_type_code => (exprf (Tbase t) * interp_base_type t)%type) t
- (x, x')) G
- -> interpf interp_op x = x')
+ Lemma interp_inline_const_gen postprocess {t} e1 e2
+ (wf : @wf _ _ t e1 e2)
(Hpostprocess : forall t e, interpf interp_op (exprf_of_inline_directive (postprocess t e)) = interpf interp_op e)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (interp interp_op (inline_const_gen postprocess e1))
- (interp interp_op e2).
+ : forall x, interp interp_op (inline_const_gen postprocess e1) x = interp interp_op e2 x.
Proof.
- induction wf.
- { eapply (interpf_inline_const_genf postprocess); eauto. }
- { simpl in *; intro.
- match goal with
- | [ H : _ |- _ ]
- => apply H; intuition (inversion_sigma; inversion_prod; subst; eauto)
- end. }
+ destruct wf.
+ simpl in *; intro; eapply (interpf_inline_const_genf postprocess); eauto.
Qed.
Local Hint Resolve interp_inline_const_gen.
- Lemma interp_inline_const is_const G {t} e1 e2
- (wf : @wf _ _ G t e1 e2)
- (H : forall t x x',
- List.In
- (existT (fun t : base_type_code => (exprf (Tbase t) * interp_base_type t)%type) t
- (x, x')) G
- -> interpf interp_op x = x')
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (interp interp_op (inline_const is_const e1))
- (interp interp_op e2).
+ Lemma interp_inline_const is_const {t} e1 e2
+ (wf : @wf _ _ t e1 e2)
+ : forall x, interp interp_op (inline_const is_const e1) x = interp interp_op e2 x.
Proof.
eapply interp_inline_const_gen; eauto.
Qed.
@@ -136,19 +117,15 @@ Section language.
Lemma InterpInlineConstGen postprocess {t} (e : Expr t)
(wf : Wf e)
(Hpostprocess : forall t e, interpf interp_op (exprf_of_inline_directive (postprocess _ t e)) = interpf interp_op e)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (Interp interp_op (InlineConstGen postprocess e))
- (Interp interp_op e).
+ : forall x, Interp interp_op (InlineConstGen postprocess e) x = Interp interp_op e x.
Proof.
unfold Interp, InlineConst.
- eapply (interp_inline_const_gen (postprocess _)); simpl in *; intuition (simpl in *; intuition eauto).
+ eapply (interp_inline_const_gen (postprocess _)); simpl; intuition.
Qed.
Lemma InterpInlineConst is_const {t} (e : Expr t)
(wf : Wf e)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (Interp interp_op (InlineConst is_const e))
- (Interp interp_op e).
+ : forall x, Interp interp_op (InlineConst is_const e) x = Interp interp_op e x.
Proof.
eapply InterpInlineConstGen; eauto.
Qed.
diff --git a/src/Reflection/InlineWf.v b/src/Reflection/InlineWf.v
index 46f4824b3..64ecb9247 100644
--- a/src/Reflection/InlineWf.v
+++ b/src/Reflection/InlineWf.v
@@ -117,7 +117,7 @@ Section language.
| _ => progress inversion_sigma
| _ => progress inversion_prod
| _ => progress destruct_head' and
- | _ => inversion_wff_step; progress subst
+ | _ => inversion_wf_step; progress subst
| _ => progress specialize_by_assumption
| _ => progress break_match
| _ => progress invert_inline_directive
@@ -168,7 +168,7 @@ Section language.
| progress destruct_head' False
| progress simpl in *
| progress invert_expr
- | progress inversion_wff
+ | progress inversion_wf
| progress break_innermost_match_step
| congruence
| solve [ auto ] ].
@@ -183,26 +183,20 @@ Section language.
: @wff var1 var2 G t (inline_constf is_const e1) (inline_constf is_const e2).
Proof. eapply wff_inline_const_genf; eauto. Qed.
- Lemma wf_inline_const_gen postprocess1 postprocess2 {t} e1 e2 G G'
- (H : forall t x x', List.In (existT (fun t : base_type_code => (exprf (Tbase t) * exprf (Tbase t))%type) t (x, x')) G'
- -> wff G x x')
- (Hwf : wf G' e1 e2)
+ Lemma wf_inline_const_gen postprocess1 postprocess2 {t} e1 e2
+ (Hwf : wf e1 e2)
(wf_postprocess : forall G t e1 e2,
wff G e1 e2
-> wff_inline_directive G (postprocess1 t e1) (postprocess2 t e2))
- : @wf var1 var2 G t (inline_const_gen postprocess1 e1) (inline_const_gen postprocess2 e2).
+ : @wf var1 var2 t (inline_const_gen postprocess1 e1) (inline_const_gen postprocess2 e2).
Proof.
- revert dependent G; induction Hwf; simpl; constructor; intros.
- { eapply wff_inline_const_genf; eauto using wff_SmartVarVarf_nil. }
- { match goal with H : _ |- _ => apply H end.
- intros; destruct_head_hnf' or; t_fin. }
+ destruct Hwf; constructor; intros.
+ eapply wff_inline_const_genf; eauto using wff_SmartVarVarf_nil.
Qed.
- Lemma wf_inline_const is_const {t} e1 e2 G G'
- (H : forall t x x', List.In (existT (fun t : base_type_code => (exprf (Tbase t) * exprf (Tbase t))%type) t (x, x')) G'
- -> wff G x x')
- (Hwf : wf G' e1 e2)
- : @wf var1 var2 G t (inline_const is_const e1) (inline_const is_const e2).
+ Lemma wf_inline_const is_const {t} e1 e2
+ (Hwf : wf e1 e2)
+ : @wf var1 var2 t (inline_const is_const e1) (inline_const is_const e2).
Proof. eapply wf_inline_const_gen; eauto. Qed.
End with_var.
@@ -214,7 +208,7 @@ Section language.
: Wf (InlineConstGen postprocess e).
Proof.
intros var1 var2.
- apply (@wf_inline_const_gen var1 var2 (postprocess _) (postprocess _) t (e _) (e _) nil nil); simpl; auto; tauto.
+ apply (@wf_inline_const_gen var1 var2 (postprocess _) (postprocess _) t (e _) (e _)); simpl; auto.
Qed.
Lemma Wf_InlineConst is_const {t} (e : Expr t)
@@ -222,7 +216,7 @@ Section language.
: Wf (InlineConst is_const e).
Proof.
intros var1 var2.
- apply (@wf_inline_const var1 var2 is_const t (e _) (e _) nil nil); simpl; try tauto.
+ apply (@wf_inline_const var1 var2 is_const t (e _) (e _)); simpl.
apply Hwf.
Qed.
End language.
diff --git a/src/Reflection/InputSyntax.v b/src/Reflection/InputSyntax.v
index 258241391..12810d20d 100644
--- a/src/Reflection/InputSyntax.v
+++ b/src/Reflection/InputSyntax.v
@@ -2,7 +2,7 @@
Require Import Coq.Strings.String.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.InterpProofs.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
@@ -17,14 +17,20 @@ Section language.
Context (base_type_code : Type).
Local Notation flat_type := (flat_type base_type_code).
- Local Notation type := (type base_type_code).
+ Inductive type := Tflat (A : flat_type) | Arrow (A : flat_type) (B : type).
Section expr_param.
Context (interp_base_type : base_type_code -> Type).
Context (op : flat_type (* input tuple *) -> flat_type (* output type *) -> Type).
- Local Notation interp_type := (interp_type interp_base_type).
Local Notation interp_flat_type_gen := interp_flat_type.
Local Notation interp_flat_type := (interp_flat_type interp_base_type).
+
+ Fixpoint interp_type (t : type) :=
+ match t with
+ | Tflat A => interp_flat_type A
+ | Arrow A B => (interp_flat_type A -> interp_type B)%type
+ end.
+
Section expr.
Context {var : flat_type -> Type}.
@@ -37,9 +43,11 @@ Section language.
| Pair : forall {t1}, exprf t1 -> forall {t2}, exprf t2 -> exprf (Prod t1 t2)
| MatchPair : forall {t1 t2}, exprf (Prod t1 t2) -> forall {tC}, (var t1 -> var t2 -> exprf tC) -> exprf tC.
Inductive expr : type -> Type :=
- | Return {t} : exprf t -> expr t
- | Abs {src dst} : (var (Tbase src) -> expr dst) -> expr (Arrow src dst).
- Global Coercion Return : exprf >-> expr.
+ | Return {T} : exprf T -> expr (Tflat T)
+ | Abs {src dst} : (var src -> expr dst) -> expr (Arrow src dst).
+
+ Definition Fst {t1 t2} (v : exprf (Prod t1 t2)) : exprf t1 := MatchPair v (fun x y => Var x).
+ Definition Snd {t1 t2} (v : exprf (Prod t1 t2)) : exprf t2 := MatchPair v (fun x y => Var y).
End expr.
Definition Expr (t : type) := forall var, @expr var t.
@@ -69,6 +77,19 @@ Section language.
Context {var : base_type_code -> Type}
(make_const : forall t, interp_base_type t -> op Unit (Tbase t)).
+ Fixpoint compilet (t : type) : Syntax.type base_type_code
+ := Syntax.Arrow
+ match t with
+ | Tflat T => Unit
+ | Arrow A (Tflat B) => A
+ | Arrow A B
+ => A * domain (compilet B)
+ end%ctype
+ match t with
+ | Tflat T => T
+ | Arrow A B => codomain (compilet B)
+ end.
+
Fixpoint SmartConst (t : flat_type) : interp_flat_type t -> Syntax.exprf base_type_code op (var:=var) t
:= match t return interp_flat_type t -> Syntax.exprf _ _ t with
| Unit => fun _ => TT
@@ -87,16 +108,36 @@ Section language.
| MatchPair _ _ ex _ eC => Syntax.LetIn (@compilef _ ex) (fun xy => @compilef _ (eC (fst xy) (snd xy)))
end.
- Fixpoint compile {t} (e : @expr (interp_flat_type_gen var) t) : @Syntax.expr base_type_code op var t
- := match e in expr t return @Syntax.expr _ _ _ t with
- | Return _ x => Syntax.Return (compilef x)
- | Abs a _ f => Syntax.Abs (fun x : var a => @compile _ (f x))
- end.
+ (* ugh, so much manual annotation *)
+ Fixpoint compile {t} (e : @expr (interp_flat_type_gen var) t) : @Syntax.expr base_type_code op var (compilet t)
+ := match e in expr t return @Syntax.expr _ _ _ (compilet t) with
+ | Return _ v => Syntax.Abs (fun _ => compilef v)
+ | Abs src dst f
+ => let res := fun x => @compile _ (f x) in
+ match dst
+ return (_ -> Syntax.expr _ _ (compilet dst))
+ -> Syntax.expr _ _ (compilet (Arrow src dst))
+ with
+ | Tflat T
+ => fun resf => Syntax.Abs (fun x => invert_Abs (resf x) tt)
+ | Arrow A B as dst'
+ => match compilet dst' as cdst
+ return (_ -> Syntax.expr _ _ cdst)
+ -> Syntax.expr _ _ (Syntax.Arrow
+ (_ * domain cdst)
+ (codomain cdst))
+ with
+ | Syntax.Arrow A' B'
+ => fun resf => Syntax.Abs (fun x : interp_flat_type_gen var (_ * _)
+ => invert_Abs (resf (fst x)) (snd x))
+ end
+ end res
+ end.
End compile.
Definition Compile
(make_const : forall t, interp_base_type t -> op Unit (Tbase t))
- {t} (e : Expr t) : Syntax.Expr base_type_code op t
+ {t} (e : Expr t) : Syntax.Expr base_type_code op (compilet t)
:= fun var => compile make_const (e _).
Section compile_correct.
@@ -127,32 +168,83 @@ Section language.
end.
Qed.
- Lemma Compile_correct {t} (e : @Expr t)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (Syntax.Interp interp_op (Compile make_const e))
- (Interp interp_op e).
+ Lemma compile_flat_correct {T} (e : expr (Tflat T))
+ : forall x, Syntax.interp interp_op (compile make_const e) x = interp interp_op e.
+ Proof.
+ intros []; simpl.
+ let G := match goal with |- ?G => G end in
+ let G := match (eval pattern T, e in G) with ?G _ _ => G end in
+ refine match e in expr t return match t return expr t -> _ with
+ | Tflat T => G T
+ | _ => fun _ => True
+ end e
+ with
+ | Return _ _ => _
+ | Abs _ _ _ => I
+ end; simpl.
+ apply compilef_correct.
+ Qed.
+
+ Lemma Compile_flat_correct_flat {T} (e : Expr (Tflat T))
+ : forall x, Syntax.Interp interp_op (Compile make_const e) x = Interp interp_op e.
+ Proof. apply compile_flat_correct. Qed.
+
+ Lemma Compile_correct {src dst} (e : @Expr (Arrow src (Tflat dst)))
+ : forall x, Syntax.Interp interp_op (Compile make_const e) x = Interp interp_op e x.
Proof.
unfold Interp, Compile, Syntax.Interp; simpl.
pose (e interp_flat_type) as E.
repeat match goal with |- context[e ?f] => change (e f) with E end.
clearbody E; clear e.
- induction E.
- { apply compilef_correct. }
- { simpl; auto. }
+ let G := match goal with |- ?G => G end in
+ let G := match (eval pattern src, dst, E in G) with ?G _ _ _ => G end in
+ refine match E in expr t return match t return expr t -> _ with
+ | Arrow src (Tflat dst) => G src dst
+ | _ => fun _ => True
+ end E
+ with
+ | Abs src dst e
+ => match dst
+ return (forall e : _ -> expr dst,
+ match dst return expr (Arrow src dst) -> _ with
+ | Tflat dst => G src dst
+ | _ => fun _ => True
+ end (Abs e))
+ with
+ | Tflat _
+ => fun e0 x
+ => _
+ | Arrow _ _ => fun _ => I
+ end e
+ | Return _ _ => I
+ end; simpl.
+ refine match e0 x as e0x in expr t
+ return match t return expr t -> _ with
+ | Tflat _
+ => fun e0x
+ => Syntax.interpf _ (invert_Abs (compile _ e0x) _)
+ = interp _ e0x
+ | _ => fun _ => True
+ end e0x
+ with
+ | Abs _ _ _ => I
+ | Return _ _ => _
+ end; simpl.
+ apply compilef_correct.
Qed.
-
- Lemma Compile_flat_correct {t : flat_type} (e : @Expr t)
- : Syntax.Interp interp_op (Compile make_const e) = Interp interp_op e.
- Proof. exact (@Compile_correct t e). Qed.
End compile_correct.
End expr_param.
End language.
+Global Arguments Arrow {_} _ _.
+Global Arguments Tflat {_} _.
Global Arguments Const {_ _ _ _ _} _.
Global Arguments Var {_ _ _ _ _} _.
Global Arguments Op {_ _ _ _ _ _} _ _.
Global Arguments LetIn {_ _ _ _ _} _ {_} _.
Global Arguments MatchPair {_ _ _ _ _ _} _ {_} _.
+Global Arguments Fst {_ _ _ _ _ _} _.
+Global Arguments Snd {_ _ _ _ _ _} _.
Global Arguments Pair {_ _ _ _ _} _ {_} _.
Global Arguments Return {_ _ _ _ _} _.
Global Arguments Abs {_ _ _ _ _ _} _.
diff --git a/src/Reflection/InterpByIso.v b/src/Reflection/InterpByIso.v
index 436ac1d96..a971b8e88 100644
--- a/src/Reflection/InterpByIso.v
+++ b/src/Reflection/InterpByIso.v
@@ -1,5 +1,6 @@
(** * PHOAS interpretation function for any retract of [var:=interp_base_type] *)
Require Import Crypto.Reflection.Syntax.
+Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.SmartMap.
Section language.
@@ -24,10 +25,9 @@ Section language.
| Pair tx ex ty ey => (@interpf_retr _ ex, @interpf_retr _ ey)
end.
- Fixpoint interp_retr {t} (e : @expr base_type_code op var t)
+ Definition interp_retr {t} (e : @expr base_type_code op var t)
: interp_type interp_base_type t
- := match e in expr _ _ t return interp_type interp_base_type t with
- | Return t ex => interpf_retr ex
- | Abs src dst f => fun x => @interp_retr _ (f (SmartVarfMap var_of_interp x))
- end.
+ := fun x => interpf_retr (invert_Abs e (SmartVarfMap var_of_interp x)).
End language.
+
+Global Arguments interp_retr _ _ _ _ _ _ _ _ !_ / _ .
diff --git a/src/Reflection/InterpByIsoProofs.v b/src/Reflection/InterpByIsoProofs.v
index c5006c3a4..2612a1c79 100644
--- a/src/Reflection/InterpByIsoProofs.v
+++ b/src/Reflection/InterpByIsoProofs.v
@@ -27,13 +27,10 @@ Section language.
induction e; simpl; cbv [LetIn.Let_In]; rewrite_hyp ?*; rewrite ?SmartVarfMap_id; reflexivity.
Qed.
Lemma interp_retr_id {t} (e : @expr interp_base_type t)
- : interp_type_gen_rel_pointwise_hetero
- (fun _ => eq)
- (fun _ => eq)
- (interp_retr (fun _ x => x) (fun _ x => x) e)
- (interp interp_op e).
+ : forall x,
+ interp_retr (fun _ x => x) (fun _ x => x) e x = interp interp_op e x.
Proof.
- induction e; simpl; repeat intro; subst; auto using interpf_retr_id.
+ destruct e; simpl; intros; rewrite interpf_retr_id, SmartVarfMap_id; reflexivity.
Qed.
Section with_var2.
@@ -80,38 +77,17 @@ Section language.
= interpf_retr var2_of_interp interp_of_var2 e2.
Proof.
induction Hwf; simpl; rewrite_hyp ?*; try reflexivity; auto.
- { match goal with H : _ |- _ => apply H end; intros.
- repeat first [ progress repeat autorewrite with core in *
- | progress subst
- | progress inversion_sigma
- | progress inversion_prod
- | progress simpl in *
- | progress destruct_head' ex
- | progress destruct_head' and
- | progress destruct_head' or
- | progress destruct_head' sigT
- | progress destruct_head' prod
- | progress rewrite_hyp !*
- | solve [ auto ] ].
- do 2 apply f_equal.
- eapply interp_flat_type_rel_pointwise_flatten_binding_list with (R':=fun _ => eq); [ eassumption | ].
- apply lift_interp_flat_type_rel_pointwise_f_eq; reflexivity. }
+ { match goal with H : _ |- _ => apply H end.
+ intros ???; rewrite List.in_app_iff.
+ intros [?|?]; eauto. }
Qed.
- Lemma wf_interp_retr G {t} (e1 : @expr var1 t) (e2 : @expr var2 t)
- (HG : forall t x1 x2,
- List.In (existT _ t (x1, x2)) G
- -> interp_of_var1 t x1 = interp_of_var2 t x2)
- (Hwf : wf G e1 e2)
- : interp_type_gen_rel_pointwise_hetero
- (fun _ => eq)
- (fun _ => eq)
- (interp_retr var1_of_interp interp_of_var1 e1)
- (interp_retr var2_of_interp interp_of_var2 e2).
+ Lemma wf_interp_retr {t} (e1 : @expr var1 t) (e2 : @expr var2 t)
+ (Hwf : wf e1 e2)
+ : forall x,
+ interp_retr var1_of_interp interp_of_var1 e1 x
+ = interp_retr var2_of_interp interp_of_var2 e2 x.
Proof.
- induction Hwf; simpl; repeat intro; subst; eauto using wff_interpf_retr.
- match goal with H : _ |- _ => apply H end.
- simpl; intros; destruct_head' or; auto.
- inversion_sigma; inversion_prod; repeat subst; unfold SmartVarfMap; simpl; auto.
+ destruct Hwf; simpl; repeat intro; subst; eapply wff_interpf_retr; eauto.
Qed.
End with_var2.
@@ -129,17 +105,13 @@ Section language.
Proof.
erewrite wff_interpf_retr, interpf_retr_id; eauto.
Qed.
- Lemma wf_interp_retr_correct G {t} (e1 : @expr var t) (e2 : @expr interp_base_type t)
- (HG : forall t x1 x2,
- List.In (existT _ t (x1, x2)) G
- -> interp_of_var t x1 = x2)
- (Hwf : wf G e1 e2)
- : interp_type_gen_rel_pointwise_hetero
- (fun _ => eq)
- (fun _ => eq)
- (interp_retr var_of_interp interp_of_var e1)
- (interp interp_op e2).
+ Lemma wf_interp_retr_correct {t} (e1 : @expr var t) (e2 : @expr interp_base_type t)
+ (Hwf : wf e1 e2)
+ x
+ : interp_retr var_of_interp interp_of_var e1 x
+ = interp interp_op e2 x.
Proof.
- Admitted.
+ erewrite wf_interp_retr, interp_retr_id; eauto.
+ Qed.
End with_var.
End language.
diff --git a/src/Reflection/InterpWf.v b/src/Reflection/InterpWf.v
index 50d05d032..b3b83698e 100644
--- a/src/Reflection/InterpWf.v
+++ b/src/Reflection/InterpWf.v
@@ -69,19 +69,10 @@ Section language.
Lemma interp_wf
{t} {e1 e2 : expr t}
- {G}
- (HG : forall t x x',
- List.In (existT (fun t : base_type_code => (interp_base_type t * interp_base_type t)%type) t (x, x')%core) G
- -> x = x')
- (Rwf : wf G e1 e2)
- : interp_type_gen_rel_pointwise (fun _ => eq) (interp e1) (interp e2).
+ (Rwf : wf e1 e2)
+ : forall x, interp e1 x = interp e2 x.
Proof.
- induction Rwf; simpl; repeat intro; simpl in *; subst; eauto.
- match goal with
- | [ H : _ |- _ ]
- => apply H; intros; progress destruct_head' or; [ | solve [ eauto ] ]
- end.
- inversion_sigma; inversion_prod; repeat subst; simpl; auto.
+ destruct Rwf; simpl; eauto.
Qed.
End wf.
End language.
diff --git a/src/Reflection/InterpWfRel.v b/src/Reflection/InterpWfRel.v
index 9106ecb5a..59ff53ffe 100644
--- a/src/Reflection/InterpWfRel.v
+++ b/src/Reflection/InterpWfRel.v
@@ -77,27 +77,18 @@ Section language.
Lemma interp_wf
{t} {e1 : expr1 t} {e2 : expr2 t}
- {G}
- (HG : forall t x x',
- List.In (existT (fun t : base_type_code => (interp_base_type1 t * interp_base_type2 t)%type) t (x, x')%core) G
- -> R t x x')
- (Rwf : wf G e1 e2)
- : interp_type_rel_pointwise2 R (interp1 e1) (interp2 e2).
+ (Rwf : wf e1 e2)
+ : interp_type_rel_pointwise R (interp1 e1) (interp2 e2).
Proof.
- induction Rwf; simpl; repeat intro; simpl in *; eauto.
- match goal with
- | [ H : _ |- _ ]
- => apply H; intros; progress destruct_head' or; [ | solve [ eauto ] ]
- end.
- inversion_sigma; inversion_prod; repeat subst; simpl; auto.
+ destruct Rwf; simpl; repeat intro; eauto.
Qed.
Lemma InterpWf
{t} {e : Expr t}
(Rwf : Wf e)
- : interp_type_rel_pointwise2 R (Interp1 e) (Interp2 e).
+ : interp_type_rel_pointwise R (Interp1 e) (Interp2 e).
Proof.
- unfold Interp, Wf in *; apply (interp_wf (G:=nil)); simpl; intuition.
+ unfold Interp, Wf in *; apply interp_wf; simpl; intuition.
Qed.
End wf.
End language.
diff --git a/src/Reflection/Linearize.v b/src/Reflection/Linearize.v
index c251c67c7..42ae9c14f 100644
--- a/src/Reflection/Linearize.v
+++ b/src/Reflection/Linearize.v
@@ -47,10 +47,9 @@ Section language.
SmartVarf (t:=Prod A B) (x, y)))
end.
- Fixpoint linearize {t} (e : expr t) : expr t
+ Definition linearize {t} (e : expr t) : expr t
:= match e in Syntax.expr _ _ t return expr t with
- | Return _ x => linearizef x
- | Abs _ _ f => Abs (fun x => @linearize _ (f x))
+ | Abs _ _ f => Abs (fun x => linearizef (f x))
end.
End with_var.
diff --git a/src/Reflection/LinearizeInterp.v b/src/Reflection/LinearizeInterp.v
index 0679fe437..e124ced5b 100644
--- a/src/Reflection/LinearizeInterp.v
+++ b/src/Reflection/LinearizeInterp.v
@@ -69,18 +69,13 @@ Section language.
Local Hint Resolve interpf_linearizef.
Lemma interp_linearize {t} e
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (interp interp_op (linearize (t:=t) e))
- (interp interp_op e).
+ : forall x, interp interp_op (linearize (t:=t) e) x = interp interp_op e x.
Proof.
- induction e; eauto.
- eapply interpf_linearizef.
+ induction e; simpl; eauto.
Qed.
Lemma InterpLinearize {t} (e : Expr t)
- : interp_type_gen_rel_pointwise (fun _ => @eq _)
- (Interp interp_op (Linearize e))
- (Interp interp_op e).
+ : forall x, Interp interp_op (Linearize e) x = Interp interp_op e x.
Proof.
unfold Interp, Linearize.
eapply interp_linearize.
diff --git a/src/Reflection/LinearizeWf.v b/src/Reflection/LinearizeWf.v
index 1c21e76be..b58ae654f 100644
--- a/src/Reflection/LinearizeWf.v
+++ b/src/Reflection/LinearizeWf.v
@@ -159,11 +159,11 @@ Section language.
Local Hint Resolve wff_linearizef.
- Lemma wf_linearize G {t} e1 e2
- : @wf var1 var2 G t e1 e2
- -> @wf var1 var2 G t (linearize e1) (linearize e2).
+ Lemma wf_linearize {t} e1 e2
+ : @wf var1 var2 t e1 e2
+ -> @wf var1 var2 t (linearize e1) (linearize e2).
Proof.
- induction 1; t_fin idtac.
+ destruct 1; constructor; auto.
Qed.
End with_var.
diff --git a/src/Reflection/MapCast.v b/src/Reflection/MapCast.v
index 50c5198ce..56736fa20 100644
--- a/src/Reflection/MapCast.v
+++ b/src/Reflection/MapCast.v
@@ -1,6 +1,6 @@
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
+Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Util.Sigma.
Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Option.
@@ -28,11 +28,6 @@ Section language.
:= (SmartValf _ (@failv _)).
Local Notation failf t (* {t} : @exprf base_type_code1 op1 ovar t*)
:= (SmartPairf (SmartFail t)).
- Fixpoint fail t : @expr base_type_code1 op1 ovar t
- := match t with
- | Tflat T => @failf _
- | Arrow A B => Abs (fun _ => @fail B)
- end.
(** We only ever make use of this when [e1] and [e2] are the same
type, and, in fact, the same syntax tree instantiated to
@@ -81,24 +76,14 @@ Section language.
end.
Arguments mapf_interp_cast {_} _ {_} _. (* 8.4 workaround for bad arguments *)
- Fixpoint map_interp_cast
+ Definition map_interp_cast
{t1} (e1 : @expr base_type_code1 op1 ovar t1)
{t2} (e2 : @expr base_type_code2 op2 interp_base_type2 t2)
- {struct e2}
- : forall (args2 : interp_all_binders_for' t2 interp_base_type2),
- @expr base_type_code1 op1 ovar t1
- := match e1 in expr _ _ t1, e2 in expr _ _ t2
- return forall (args2 : interp_all_binders_for' t2 _), expr _ _ t1 with
- | Return t1 ex1, Return t2 ex2
- => fun _ => mapf_interp_cast ex1 ex2
- | Abs src1 dst1 f1, Abs src2 dst2 f2
- => fun args2
- => Abs (fun x
- => @map_interp_cast _ (f1 x) _ (f2 (fst args2)) (snd args2))
- | Return _ _, _
- | Abs _ _ _, _
- => fun _ => @fail _
- end.
+ (args2 : interp_flat_type interp_base_type2 (domain t2))
+ : @expr base_type_code1 op1 ovar (Arrow (domain t1) (codomain t1))
+ := let f1 := invert_Abs e1 in
+ let f2 := invert_Abs e2 in
+ Abs (fun x => @mapf_interp_cast _ (f1 x) _ (f2 args2)).
End with_var.
End language.
@@ -114,7 +99,7 @@ Section homogenous.
Definition MapInterpCast
transfer_op
- {t} (e : Expr base_type_code op t) args
- : Expr base_type_code op t
+ {t} (e : Expr base_type_code op t) (args : interp_flat_type interp_base_type2 (domain t))
+ : Expr base_type_code op (Arrow (domain t) (codomain t))
:= fun var => map_interp_cast interp_op2 (@failv) transfer_op (e _) (e _) args.
End homogenous.
diff --git a/src/Reflection/MapCastInterp.v b/src/Reflection/MapCastInterp.v
index cb5b57986..e3f93af86 100644
--- a/src/Reflection/MapCastInterp.v
+++ b/src/Reflection/MapCastInterp.v
@@ -2,7 +2,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.MapCast.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.WfProofs.
@@ -133,7 +132,7 @@ Section language.
Local Ltac break_t
:= first [ progress subst
- | progress inversion_wff
+ | progress inversion_wf
| progress invert_expr_subst
| progress inversion_sigma
| progress inversion_prod
@@ -243,61 +242,50 @@ Section language.
Proof. eapply interpf_mapf_interp_cast_and_rel; eassumption. Qed.
Lemma interp_map_interp_cast_and_rel
- G {t1} e1 ebounds
+ {t1} e1 ebounds
args2
- (Hgood : bounds_are_recursively_good bound_is_good (ApplyAll ebounds (interp_all_binders_for_of' args2)))
- (HG : G_invariant_holds G)
- (Hwf : wf G e1 ebounds)
+ (Hgood : bounds_are_recursively_good bound_is_good (invert_Abs ebounds args2))
+ (Hwf : wf e1 ebounds)
: forall x,
R x args2
- -> ApplyInterpedAll'
- (interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2)) x
- = ApplyInterpedAll' (interp interp_op1 e1) x
- /\ R (ApplyInterpedAll'
- (interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2)) x)
- (ApplyInterpedAll' (interp interp_op2 ebounds) args2).
- Proof.
- induction Hwf; intros.
- { eapply interpf_mapf_interp_cast_and_rel; eauto. }
- { simpl; match goal with H : _ |- _ => apply H end; eauto.
- admit.
- admit.
- admit. }
- Admitted.
+ -> interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2) x
+ = interp interp_op1 e1 x
+ /\ R (interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2) x)
+ (interp interp_op2 ebounds args2).
+ Proof. destruct Hwf; intros; eapply interpf_mapf_interp_cast_and_rel; eauto. Qed.
Lemma interp_map_interp_cast
- G {t1} e1 ebounds
+ {t1} e1 ebounds
args2
- (Hgood : bounds_are_recursively_good bound_is_good (ApplyAll ebounds (interp_all_binders_for_of' args2)))
- (HG : G_invariant_holds G)
- (Hwf : wf G e1 ebounds)
+ (Hgood : bounds_are_recursively_good bound_is_good (invert_Abs ebounds args2))
+ (Hwf : wf e1 ebounds)
: forall x,
R x args2
- -> ApplyInterpedAll' (interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2)) x
- = ApplyInterpedAll' (interp interp_op1 e1) x.
+ -> interp interp_op1 (@map_interp_cast interp_base_type1 t1 e1 t1 ebounds args2) x
+ = interp interp_op1 e1 x.
Proof. intros; eapply interp_map_interp_cast_and_rel; eassumption. Qed.
Lemma InterpMapInterpCastAndRel
{t} e
args
(Hwf : Wf e)
- (Hgood : bounds_are_recursively_good bound_is_good (ApplyAll (e interp_base_type2) (interp_all_binders_for_of' args)))
+ (Hgood : bounds_are_recursively_good bound_is_good (invert_Abs (e interp_base_type2) args))
: forall x,
R x args
- -> ApplyInterpedAll' (Interp interp_op1 (@MapInterpCast t e args)) x
- = ApplyInterpedAll' (Interp interp_op1 e) x
- /\ R (ApplyInterpedAll' (Interp interp_op1 (@MapInterpCast t e args)) x)
- (ApplyInterpedAll' (Interp interp_op2 e) args).
- Proof. eapply interp_map_interp_cast_and_rel; eauto; simpl; tauto. Qed.
+ -> Interp interp_op1 (@MapInterpCast t e args) x
+ = Interp interp_op1 e x
+ /\ R (Interp interp_op1 (@MapInterpCast t e args) x)
+ (Interp interp_op2 e args).
+ Proof. apply interp_map_interp_cast_and_rel; auto. Qed.
Lemma InterpMapInterpCast
{t} e
args
(Hwf : Wf e)
- (Hgood : bounds_are_recursively_good bound_is_good (ApplyAll (e interp_base_type2) (interp_all_binders_for_of' args)))
+ (Hgood : bounds_are_recursively_good bound_is_good (invert_Abs (e interp_base_type2) args))
: forall x,
R x args
- -> ApplyInterpedAll' (Interp interp_op1 (@MapInterpCast t e args)) x
- = ApplyInterpedAll' (Interp interp_op1 e) x.
- Proof. eapply interp_map_interp_cast; eauto; simpl; tauto. Qed.
+ -> Interp interp_op1 (@MapInterpCast t e args) x
+ = Interp interp_op1 e x.
+ Proof. apply interp_map_interp_cast; auto. Qed.
End language.
diff --git a/src/Reflection/MapCastWf.v b/src/Reflection/MapCastWf.v
index 72a818608..717f8de60 100644
--- a/src/Reflection/MapCastWf.v
+++ b/src/Reflection/MapCastWf.v
@@ -83,7 +83,7 @@ Section language.
Local Ltac break_t
:= first [ progress subst
- | progress inversion_wff
+ | progress inversion_wf
| progress invert_expr_subst
| progress inversion_sigma
| progress inversion_prod
@@ -123,7 +123,7 @@ Section language.
end.
Qed.
- (*Lemma wf_map_interp_cast
+ Lemma wf_map_interp_cast
{t1} e1 e2 ebounds
args2
(Hwf_bounds : wf e1 ebounds)
@@ -141,7 +141,7 @@ Section language.
| [ |- wf _ _ ] => constructor
| _ => solve [ eauto using wff_SmartVarf, wff_in_impl_Proper ]
end.
- Qed.*)
+ Qed.
End with_var.
Section gen.
@@ -152,7 +152,6 @@ Section language.
(@transfer_op ovar1 src1 dst1 src2 dst2 opc1 opc2 e1 args2)
(@transfer_op ovar2 src1 dst1 src2 dst2 opc1 opc2 e2 args2)).
- Axiom proof_admitted : False.
Local Notation MapInterpCast
:= (@MapInterpCast
base_type_code interp_base_type
@@ -165,9 +164,7 @@ Section language.
(Hwf : Wf e)
: Wf (@MapInterpCast t e args).
Proof.
- revert wff_transfer_op.
- case proof_admitted.
- (*intros ??; apply wf_map_interp_cast; auto.*)
+ intros ??; apply wf_map_interp_cast; auto.
Qed.
End gen.
End language.
diff --git a/src/Reflection/MultiSizeTest2.v b/src/Reflection/MultiSizeTest2.v
index afd53bd19..575b8978a 100644
--- a/src/Reflection/MultiSizeTest2.v
+++ b/src/Reflection/MultiSizeTest2.v
@@ -151,19 +151,20 @@ Definition Boundify {t1} (e1 : Expr base_type op t1) args2
(** * Examples *)
-Example ex1 : Expr base_type op TNat := fun var =>
+Example ex1 : Expr base_type op (Arrow Unit TNat) := fun var =>
+ Abs (fun _ =>
LetIn (Constf (t:=Nat) 127) (fun a : var Nat =>
LetIn (Constf (t:=Nat) 63) (fun b : var Nat =>
LetIn (Op (tR:=TNat) (Plus Nat) (Pair (Var a) (Var b))) (fun c : var Nat =>
- Op (Plus Nat) (Pair (Var c) (Var c))))).
+ Op (Plus Nat) (Pair (Var c) (Var c)))))).
-Example ex1f : Expr base_type op (Arrow Nat (Arrow Nat TNat)) := fun var =>
- Abs (fun a0 =>
- Abs (fun b0 =>
+Example ex1f : Expr base_type op (Arrow (TNat * TNat) TNat) := fun var =>
+ Abs (fun a0b0 : interp_flat_type _ (TNat * TNat) =>
+ let a0 := fst a0b0 in let b0 := snd a0b0 in
LetIn (Var a0) (fun a : var Nat =>
LetIn (Var b0) (fun b : var Nat =>
LetIn (Op (tR:=TNat) (Plus Nat) (Pair (Var a) (Var b))) (fun c : var Nat =>
- Op (Plus Nat) (Pair (Var c) (Var c))))))).
+ Op (Plus Nat) (Pair (Var c) (Var c)))))).
Eval compute in (Interp (@interp_op) ex1).
Eval cbv -[plus] in (Interp (@interp_op) ex1f).
diff --git a/src/Reflection/Named/Compile.v b/src/Reflection/Named/Compile.v
index 7ffc5fded..55f4aba70 100644
--- a/src/Reflection/Named/Compile.v
+++ b/src/Reflection/Named/Compile.v
@@ -38,14 +38,13 @@ Section language.
end
end.
- Fixpoint ocompile {t} (e : expr t) (ls : list (option Name)) {struct e}
+ Definition ocompile {t} (e : expr t) (ls : list (option Name))
: option (nexpr t)
:= match e in @Syntax.expr _ _ _ t return option (nexpr t) with
- | Return _ x => option_map Named.Return (ocompilef x ls)
- | Abs _ _ f
- => match ls with
- | cons (Some n) ls'
- => option_map (Named.Abs n) (@ocompile _ (f n) ls')
+ | Abs src _ f
+ => match split_onames src ls with
+ | (Some n, ls')%core
+ => option_map (Named.Abs n) (@ocompilef _ (f n) ls')
| _ => None
end
end.
diff --git a/src/Reflection/Named/EstablishLiveness.v b/src/Reflection/Named/EstablishLiveness.v
index bd9a46b9a..7509d5f7a 100644
--- a/src/Reflection/Named/EstablishLiveness.v
+++ b/src/Reflection/Named/EstablishLiveness.v
@@ -68,15 +68,14 @@ Section language.
Fixpoint compute_livenessf ctx {t} e prefix
:= @compute_livenessf_step (@compute_livenessf) ctx t e prefix.
- Fixpoint compute_liveness (ctx : Context)
+ Definition compute_liveness (ctx : Context)
{t} (e : expr Name t) (prefix : list liveness)
: list liveness
:= match e with
- | Return _ x => compute_livenessf ctx x prefix
| Abs src _ n f
- => let prefix := prefix ++ repeat live (count_pairs (Tbase src)) in
- let ctx := extend (t:=Tbase src) ctx n (SmartValf _ (fun _ => prefix) (Tbase src)) in
- @compute_liveness ctx _ f prefix
+ => let prefix := prefix ++ repeat live (count_pairs src) in
+ let ctx := extend (t:=src) ctx n (SmartValf _ (fun _ => prefix) src) in
+ compute_livenessf ctx f prefix
end.
Section insert_dead.
diff --git a/src/Reflection/Named/RegisterAssign.v b/src/Reflection/Named/RegisterAssign.v
index ce8188ee5..70ee5a203 100644
--- a/src/Reflection/Named/RegisterAssign.v
+++ b/src/Reflection/Named/RegisterAssign.v
@@ -67,18 +67,17 @@ Section language.
Fixpoint register_reassignf ctxi ctxr {t} e new_names
:= @register_reassignf_step (@register_reassignf) ctxi ctxr t e new_names.
- Fixpoint register_reassign (ctxi : InContext) (ctxr : ReverseContext)
+ Definition register_reassign (ctxi : InContext) (ctxr : ReverseContext)
{t} (e : expr InName t) (new_names : list (option OutName))
: option (expr OutName t)
:= match e in Named.expr _ _ _ t return option (expr _ t) with
- | Return _ x => option_map Return (register_reassignf ctxi ctxr x new_names)
| Abs src _ n f
- => let '(n', new_names') := eta (split_onames (Tbase src) new_names) in
+ => let '(n', new_names') := eta (split_onames src new_names) in
match n' with
| Some n'
- => let ctxi := extendb (t:=src) ctxi n n' in
- let ctxr := extendb (t:=src) ctxr n' n in
- option_map (Abs n') (@register_reassign ctxi ctxr _ f new_names')
+ => let ctxi := extend (t:=src) ctxi n n' in
+ let ctxr := extend (t:=src) ctxr n' n in
+ option_map (Abs n') (register_reassignf ctxi ctxr f new_names')
| None => None
end
end.
diff --git a/src/Reflection/Named/Syntax.v b/src/Reflection/Named/Syntax.v
index 2c1f3bd23..996d707a3 100644
--- a/src/Reflection/Named/Syntax.v
+++ b/src/Reflection/Named/Syntax.v
@@ -47,10 +47,8 @@ Module Export Named.
| Pair : forall {t1}, exprf t1 -> forall {t2}, exprf t2 -> exprf (Prod t1 t2).
Bind Scope nexpr_scope with exprf.
Inductive expr : type -> Type :=
- | Return {t} : exprf t -> expr t
- | Abs {src dst} : Name -> expr dst -> expr (Arrow src dst).
+ | Abs {src dst} : interp_flat_type_gen (fun _ => Name) src -> exprf dst -> expr (Arrow src dst).
Bind Scope nexpr_scope with expr.
- Global Coercion Return : exprf >-> expr.
(** [SmartVar] is like [Var], except that it inserts
pair-projections and [Pair] as necessary to handle
[flat_type], and not just [base_type_code] *)
@@ -110,10 +108,9 @@ Module Export Named.
| Pair _ ex _ ey => @wff ctx _ ex /\ @wff ctx _ ey
end%option_pointed_prop.
- Fixpoint wf (ctx : Context) {t} (e : expr t) : Prop
+ Definition wf (ctx : Context) {t} (e : expr t) : Prop
:= match e with
- | Return _ x => prop_of_option (wff ctx x)
- | Abs src _ n f => forall v, @wf (extend ctx (t:=Tbase src) n v) _ f
+ | Abs src _ n f => forall v, prop_of_option (@wff (extend ctx (t:=src) n v) _ f)
end.
End wf.
@@ -166,11 +163,10 @@ Module Export Named.
tt (fun _ x => x) interp_op (fun _ y _ f => let x := y in f x)
(fun _ x _ y => (x, y)%core).
- Fixpoint interp (ctx : Context) {t} (e : expr t)
+ Definition interp (ctx : Context) {t} (e : expr t)
: wf ctx e -> interp_type t
:= match e in expr t return wf ctx e -> interp_type t with
- | Return _ x => interpf ctx x
- | Abs _ _ n f => fun good v => @interp _ _ f (good v)
+ | Abs _ _ n f => fun good v => @interpf _ _ f (good v)
end.
End with_val_context.
End expr_param.
@@ -183,7 +179,6 @@ Global Arguments SmartVar {_ _ _ _} _.
Global Arguments Op {_ _ _ _ _} _ _.
Global Arguments LetIn {_ _ _} _ _ _ {_} _.
Global Arguments Pair {_ _ _ _} _ {_} _.
-Global Arguments Return {_ _ _ _} _.
Global Arguments Abs {_ _ _ _ _} _ _.
Global Arguments extend {_ _ _ _} ctx {_} _ _.
Global Arguments remove {_ _ _ _} ctx {_} _.
diff --git a/src/Reflection/Reify.v b/src/Reflection/Reify.v
index 9b3c70d49..99518657b 100644
--- a/src/Reflection/Reify.v
+++ b/src/Reflection/Reify.v
@@ -81,16 +81,21 @@ Ltac reify_flat_type T :=
=> let v := reify_base_type T in
constr:(@Tbase _ v)
end.
-Ltac reify_type T :=
+Ltac reify_input_type T :=
let dummy := debug_enter_reify_type T in
lazymatch T with
| (?A -> ?B)%type
- => let a := reify_base_type A in
- let b := reify_type B in
+ => let a := reify_flat_type A in
+ let b := reify_input_type B in
constr:(@Arrow _ a b)
- | _
- => let v := reify_flat_type T in
- constr:(@Tflat _ v)
+ end.
+Ltac reify_type T :=
+ let dummy := debug_enter_reify_type T in
+ lazymatch T with
+ | (?A -> ?B)%type
+ => let a := reify_flat_type A in
+ let b := reify_flat_type B in
+ constr:(@Syntax.Arrow _ a b)
end.
Ltac reifyf_var x mkVar :=
@@ -140,6 +145,8 @@ Ltac reifyf base_type_code interp_base_type op var e :=
let mkConst T ex := constr:(Const (base_type_code:=base_type_code) (interp_base_type:=interp_base_type) (op:=op) (var:=var) (t:=T) ex) in
let mkOp T retT op_code args := constr:(Op (base_type_code:=base_type_code) (interp_base_type:=interp_base_type) (op:=op) (var:=var) (t1:=T) (tR:=retT) op_code args) in
let mkMatchPair tC ex eC := constr:(MatchPair (base_type_code:=base_type_code) (interp_base_type:=interp_base_type) (op:=op) (var:=var) (tC:=tC) ex eC) in
+ let mkFst ex := constr:(Fst (base_type_code:=base_type_code) (interp_base_type:=interp_base_type) (op:=op) (var:=var) ex) in
+ let mkSnd ex := constr:(Snd (base_type_code:=base_type_code) (interp_base_type:=interp_base_type) (op:=op) (var:=var) ex) in
let reify_tag := constr:(@exprf base_type_code interp_base_type op var) in
let dummy := debug_enter_reifyf e in
lazymatch e with
@@ -172,10 +179,20 @@ Ltac reifyf base_type_code interp_base_type op var e :=
with fun _ v _ => @?C v => C end
| match ?ev with pair a b => @?eC a b end =>
let dummy := debug_reifyf_case "matchpair" in
- let t := (let T := match type of eC with _ -> _ -> ?T => T end in reify_flat_type T) in
+ let T := type of eC in
+ let t := (let T := match (eval cbv beta in T) with _ -> _ -> ?T => T end in reify_flat_type T) in
let v := reify_rec ev in
let C := reify_rec eC in
- mkMatchPair t v C
+ let ret := mkMatchPair t v C in
+ ret
+ | @fst ?A ?B ?ev =>
+ let dummy := debug_reifyf_case "fst" in
+ let v := reify_rec ev in
+ mkFst v
+ | @snd ?A ?B ?ev =>
+ let dummy := debug_reifyf_case "snd" in
+ let v := reify_rec ev in
+ mkSnd v
| ?x =>
let dummy := debug_reifyf_case "generic" in
let t := lazymatch type of x with ?t => reify_flat_type t end in
@@ -256,14 +273,14 @@ Ltac reify_abs base_type_code interp_base_type op var e :=
let dummy := debug_enter_reify_abs e in
lazymatch e with
| (fun x : ?T => ?C) =>
- let t := reify_base_type T in
+ let t := reify_flat_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. *)
let maybe_x := fresh x in
let not_x := fresh x in
- lazymatch constr:(fun (x : T) (not_x : var (Tbase t)) (_ : reify_var_for_in_is base_type_code x (Tbase t) not_x) =>
+ lazymatch constr:(fun (x : T) (not_x : var t) (_ : reify_var_for_in_is base_type_code x t not_x) =>
(_ : reify_abs reify_tag C)) (* [C] here is an open term that references "x" by name *)
with fun _ v _ => @?C v => mkAbs t C end
| ?x =>
@@ -280,29 +297,44 @@ Ltac Reify' base_type_code interp_base_type op e :=
end.
Ltac Reify base_type_code interp_base_type op make_const e :=
let r := Reify' base_type_code interp_base_type op e in
+ let r := lazymatch type of r with
+ | forall var, exprf _ _ _ _ => constr:(fun var => Abs (src:=Unit) (fun _ => r var))
+ | _ => r
+ end in
constr:(@InputSyntax.Compile base_type_code interp_base_type op make_const _ r).
-Ltac lhs_of_goal := lazymatch goal with |- ?R ?LHS ?RHS => LHS end.
-Ltac rhs_of_goal := lazymatch goal with |- ?R ?LHS ?RHS => RHS end.
+Ltac rhs_of_goal :=
+ lazymatch goal with
+ | [ |- ?R ?LHS ?RHS ] => RHS
+ | [ |- forall x, ?R (@?LHS x) (@?RHS x) ] => RHS
+ end.
+
+Ltac transitivity_tt term :=
+ first [ transitivity term
+ | transitivity (term tt)
+ | let x := fresh in intro x; transitivity (term x); revert x ].
Ltac Reify_rhs_gen Reify prove_interp_compile_correct interp_op try_tac :=
let rhs := rhs_of_goal in
let RHS := Reify rhs in
let RHS' := (eval vm_compute in RHS) in
- transitivity (Syntax.Interp interp_op RHS');
+ transitivity_tt (Syntax.Interp interp_op RHS');
[
- | transitivity (Syntax.Interp interp_op RHS);
+ | transitivity_tt (Syntax.Interp interp_op RHS);
[ lazymatch goal with
| [ |- ?R ?x ?y ]
=> cut (x = y)
+ | [ |- forall k, ?R (?x k) (?y k) ]
+ => cut (x = y)
end;
[ let H := fresh in
intro H; rewrite H; reflexivity
| apply f_equal; vm_compute; reflexivity ]
- | etransitivity; (* first we strip off the [InputSyntax.Compile]
- bit; Coq is bad at inferring the type, so we
- help it out by providing it *)
- [ prove_interp_compile_correct ()
+ | intros; etransitivity; (* first we strip off the [InputSyntax.Compile]
+ bit; Coq is bad at inferring the type, so we
+ help it out by providing it *)
+ [ cbv [InputSyntax.compilet];
+ prove_interp_compile_correct ()
| try_tac
ltac:(fun _
=> (* now we unfold the interpretation function,
@@ -311,7 +343,7 @@ Ltac Reify_rhs_gen Reify prove_interp_compile_correct interp_op try_tac :=
functions that we're parameterized over. *)
abstract (
lazymatch goal with
- | [ |- ?R (@InputSyntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op ?t ?e) _ ]
+ | [ |- appcontext[@InputSyntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op ?t ?e] ]
=> let interp_base_type' := (eval hnf in interp_base_type) in
let interp_op' := (eval hnf in interp_op) in
change interp_base_type with interp_base_type';
@@ -320,13 +352,15 @@ Ltac Reify_rhs_gen Reify prove_interp_compile_correct interp_op try_tac :=
cbv iota beta delta [InputSyntax.Interp interp_type interp_type_gen interp_type_gen_hetero interp_flat_type interp interpf]; reflexivity)) ] ] ].
Ltac prove_compile_correct :=
- fun _ => lazymatch goal with
- | [ |- @Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op (@Tflat _ ?t) (@Compile _ _ _ ?make_const _ ?e) = _ ]
- => apply (fun pf => @InputSyntax.Compile_flat_correct base_type_code interp_base_type op make_const interp_op pf t e)
- | [ |- interp_type_gen_rel_pointwise _ (@Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op ?t (@Compile _ _ _ ?make_const _ ?e)) _ ]
- => apply (fun pf => @InputSyntax.Compile_correct base_type_code interp_base_type op make_const interp_op pf t e)
- end;
- let T := fresh in intro T; destruct T; reflexivity.
+ fun _ => intros;
+ lazymatch goal with
+ | [ |- @Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op _ (@Compile _ _ _ ?make_const (InputSyntax.Arrow ?src (Tflat ?dst)) ?e) ?x = _ ]
+ => apply (fun pf => @InputSyntax.Compile_correct base_type_code interp_base_type op make_const interp_op pf src dst e x);
+ let T := fresh in intro T; destruct T; reflexivity
+ | [ |- @Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op _ (@Compile _ _ _ ?make_const (Tflat ?T) ?e) ?x = _ ]
+ => apply (fun pf => @InputSyntax.Compile_flat_correct_flat base_type_code interp_base_type op make_const interp_op pf T e x);
+ let T := fresh in intro T; destruct T; reflexivity
+ end.
Ltac Reify_rhs base_type_code interp_base_type op make_const interp_op :=
Reify_rhs_gen
diff --git a/src/Reflection/Relations.v b/src/Reflection/Relations.v
index 4109651c8..160d76b56 100644
--- a/src/Reflection/Relations.v
+++ b/src/Reflection/Relations.v
@@ -162,20 +162,17 @@ Section language.
Section type.
Section hetero.
- Context (interp_src1 interp_src2 : base_type_code -> Type)
+ Context (interp_src1 interp_src2 : flat_type -> Type)
(interp_dst1 interp_dst2 : flat_type -> Type).
Section hetero.
Context (Rsrc : forall t, interp_src1 t -> interp_src2 t -> Prop)
(Rdst : forall t, interp_dst1 t -> interp_dst2 t -> Prop).
- Fixpoint interp_type_gen_rel_pointwise_hetero (t : type)
+ Definition interp_type_gen_rel_pointwise_hetero (t : type)
: interp_type_gen_hetero interp_src1 interp_dst1 t
-> interp_type_gen_hetero interp_src2 interp_dst2 t
-> Prop
- := match t with
- | Tflat t => Rdst t
- | Arrow src dst => @respectful_hetero _ _ _ _ (Rsrc src) (fun _ _ => interp_type_gen_rel_pointwise_hetero dst)
- end.
+ := @respectful_hetero _ _ _ _ (Rsrc _) (fun _ _ => Rdst _).
Global Arguments interp_type_gen_rel_pointwise_hetero _ _ _ / .
End hetero.
Section hetero_hetero.
@@ -186,14 +183,7 @@ Section language.
: interp_type_gen_hetero interp_src1 interp_dst1 t1
-> interp_type_gen_hetero interp_src2 interp_dst2 t2
-> Prop
- := match t1, t2 with
- | Tflat t1, Tflat t2 => Rdst t1 t2
- | Arrow src1 dst1, Arrow src2 dst2
- => @respectful_hetero _ _ _ _ (Rsrc src1 src2) (fun _ _ => interp_type_gen_rel_pointwise_hetero_hetero dst1 dst2)
- | Tflat _, _
- | Arrow _ _, _
- => fun _ _ => False
- end.
+ := @respectful_hetero _ _ _ _ (Rsrc _ _) (fun _ _ => Rdst _ _).
Global Arguments interp_type_gen_rel_pointwise_hetero_hetero _ _ _ _ / .
End hetero_hetero.
End hetero.
@@ -202,63 +192,36 @@ Section language.
Context (interp_flat_type1 interp_flat_type2 : flat_type -> Type)
(R : forall t, interp_flat_type1 t -> interp_flat_type2 t -> Prop).
- Definition interp_type_gen_rel_pointwise2
+ Definition interp_type_gen_rel_pointwise
: forall t,
interp_type_gen interp_flat_type1 t
-> interp_type_gen interp_flat_type2 t
-> Prop
:= interp_type_gen_rel_pointwise_hetero
- (fun t => interp_flat_type1 (Tbase t)) (fun t => interp_flat_type2 (Tbase t))
interp_flat_type1 interp_flat_type2
- (fun t => R (Tbase t)) R.
- Global Arguments interp_type_gen_rel_pointwise2 _ _ _ / .
+ interp_flat_type1 interp_flat_type2
+ R R.
+ Global Arguments interp_type_gen_rel_pointwise _ _ _ / .
End partially_hetero.
-
- Section homogenous.
- Context (interp_flat_type : flat_type -> Type)
- (R : forall t, interp_flat_type t -> interp_flat_type t -> Prop).
- Local Notation interp_type_gen := (interp_type_gen interp_flat_type).
- Fixpoint interp_type_gen_rel_pointwise (t : type)
- : interp_type_gen t -> interp_type_gen t -> Prop :=
- match t with
- | Tflat t => R t
- | Arrow _ y => fun f g => forall x, interp_type_gen_rel_pointwise y (f x) (g x)
- end.
- Global Instance interp_type_gen_rel_pointwise_Reflexive {H : forall t, Reflexive (R t)}
- : forall t, Reflexive (interp_type_gen_rel_pointwise t).
- Proof. induction t; repeat intro; reflexivity. Qed.
- Global Instance interp_type_gen_rel_pointwise_Symmetric {H : forall t, Symmetric (R t)}
- : forall t, Symmetric (interp_type_gen_rel_pointwise t).
- Proof. induction t; simpl; repeat intro; symmetry; eauto. Qed.
- Global Instance interp_type_gen_rel_pointwise_Transitive {H : forall t, Transitive (R t)}
- : forall t, Transitive (interp_type_gen_rel_pointwise t).
- Proof. induction t; simpl; repeat intro; etransitivity; eauto. Qed.
- End homogenous.
End type.
Section specialized_type.
Section hetero.
Context (interp_base_type1 interp_base_type2 : base_type_code -> Type).
- Definition interp_type_rel_pointwise2 R
+ Definition interp_type_rel_pointwise R
: forall t, interp_type interp_base_type1 t
-> interp_type interp_base_type2 t
-> Prop
- := interp_type_gen_rel_pointwise2 _ _ (interp_flat_type_rel_pointwise R).
- Global Arguments interp_type_rel_pointwise2 _ !_ _ _ / .
+ := interp_type_gen_rel_pointwise _ _ (interp_flat_type_rel_pointwise R).
+ Global Arguments interp_type_rel_pointwise _ !_ _ _ / .
- Definition interp_type_rel_pointwise2_hetero R
+ Definition interp_type_rel_pointwise_hetero R
: forall t1 t2, interp_type interp_base_type1 t1
-> interp_type interp_base_type2 t2
-> Prop
- := interp_type_gen_rel_pointwise_hetero_hetero _ _ _ _ (fun t1 t2 => interp_flat_type_rel_pointwise_hetero R (Tbase t1) (Tbase t2)) (interp_flat_type_rel_pointwise_hetero R).
- Global Arguments interp_type_rel_pointwise2_hetero _ !_ !_ _ _ / .
+ := interp_type_gen_rel_pointwise_hetero_hetero _ _ _ _ (interp_flat_type_rel_pointwise_hetero R) (interp_flat_type_rel_pointwise_hetero R).
+ Global Arguments interp_type_rel_pointwise_hetero _ !_ !_ _ _ / .
End hetero.
-
- Section homogenous.
- Context {interp_base_type : base_type_code -> Type}.
- Definition interp_type_rel_pointwise R
- := interp_type_gen_rel_pointwise _ (@interp_flat_type_rel_pointwise interp_base_type interp_base_type R).
- End homogenous.
End specialized_type.
Section lifting.
@@ -324,6 +287,30 @@ Section language.
induction t; unfold SmartVarfMap2 in *; simpl in *; destruct_head_hnf unit; try tauto.
rewrite_hyp !*; intuition congruence.
Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq {T} (f g : forall t, _ -> T t) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = g t y)
+ t x y
+ <-> (forall a b, SmartVarfMap f a = SmartVarfMap g b -> SmartVarfMap f (x a) = SmartVarfMap g (y b)).
+ Proof.
+ destruct t; simpl; unfold interp_type_rel_pointwise, respectful_hetero.
+ setoid_rewrite lift_interp_flat_type_rel_pointwise_f_eq; reflexivity.
+ Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq_id1 (f : forall t, _ -> _) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => x = f t y)
+ t x y
+ <-> (forall a, x (SmartVarfMap f a) = SmartVarfMap f (y a)).
+ Proof. rewrite lift_interp_type_rel_pointwise_f_eq; setoid_rewrite SmartVarfMap_id; firstorder (subst; eauto). Qed.
+ Lemma lift_interp_type_rel_pointwise_f_eq_id2 (f : forall t, _ -> _) t x y
+ : interp_type_rel_pointwise
+ interp_base_type1 interp_base_type2
+ (fun t x y => f t x = y)
+ t x y
+ <-> (forall a, SmartVarfMap f (x a) = y (SmartVarfMap f a)).
+ Proof. rewrite lift_interp_type_rel_pointwise_f_eq; setoid_rewrite SmartVarfMap_id; firstorder (subst; eauto). Qed.
End lifting.
Local Ltac t :=
@@ -359,11 +346,11 @@ Section language.
Qed.
End language.
-Global Arguments interp_type_rel_pointwise2 {_ _ _} R {t} _ _.
-Global Arguments interp_type_rel_pointwise2_hetero {_ _ _} R {t1 t2} _ _.
+Global Arguments interp_type_rel_pointwise {_ _ _} R {t} _ _.
+Global Arguments interp_type_rel_pointwise_hetero {_ _ _} R {t1 t2} _ _.
Global Arguments interp_type_gen_rel_pointwise_hetero_hetero {_ _ _ _ _} Rsrc Rdst {t1 t2} _ _.
Global Arguments interp_type_gen_rel_pointwise_hetero {_ _ _ _ _} Rsrc Rdst {t} _ _.
-Global Arguments interp_type_gen_rel_pointwise2 {_ _ _} R {t} _ _.
+Global Arguments interp_type_gen_rel_pointwise {_ _ _} R {t} _ _.
Global Arguments interp_flat_type_rel_pointwise_gen_Prop {_ _ _ P} and True R {t} _ _.
Global Arguments interp_flat_type_rel_pointwise_hetero_gen_Prop {_ _ _ P} and True False R {t1 t2} _ _.
Global Arguments interp_flat_type_rel_pointwise_hetero {_ _ _} R {t1 t2} _ _.
@@ -372,5 +359,3 @@ Global Arguments interp_flat_type_rel_pointwise1 {_ _} R {t} _.
Global Arguments interp_flat_type_relb_pointwise1 {_ _} R {t} _.
Global Arguments interp_flat_type_rel_pointwise {_ _ _} R {t} _ _.
Global Arguments interp_flat_type_relb_pointwise {_ _ _} R {t} _ _.
-Global Arguments interp_type_rel_pointwise {_} _ _ {_} _ _.
-Global Arguments interp_type_gen_rel_pointwise {_ _} _ {_} _ _.
diff --git a/src/Reflection/SmartBound.v b/src/Reflection/SmartBound.v
index d86771216..15eeb7b12 100644
--- a/src/Reflection/SmartBound.v
+++ b/src/Reflection/SmartBound.v
@@ -1,7 +1,7 @@
Require Import Crypto.Reflection.Syntax.
+Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.TypeUtil.
Require Import Crypto.Reflection.SmartCast.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Util.Notations.
@@ -35,16 +35,12 @@ Section language.
Definition bound_flat_type {t} : interp_flat_type interp_base_type_bounds t
-> flat_type
:= @SmartFlatTypeMap2 _ _ interp_base_type_bounds (fun t v => Tbase (bound_base_type t v)) t.
- Fixpoint bound_type {t} : forall (e_bounds : interp_type interp_base_type_bounds t)
- (input_bounds : interp_all_binders_for' t interp_base_type_bounds),
- type
- := match t return interp_type _ t -> interp_all_binders_for' t _ -> type with
- | Tflat T => fun e_bounds _ => @bound_flat_type T e_bounds
- | Arrow A B
- => fun e_bounds input_bounds
- => Arrow (@bound_base_type A (fst input_bounds))
- (@bound_type B (e_bounds (fst input_bounds)) (snd input_bounds))
- end.
+ Definition bound_type {t}
+ (e_bounds : interp_type interp_base_type_bounds t)
+ (input_bounds : interp_flat_type interp_base_type_bounds (domain t))
+ : type
+ := Arrow (@bound_flat_type (domain t) input_bounds)
+ (@bound_flat_type (codomain t) (e_bounds input_bounds)).
Definition bound_op
ovar src1 dst1 src2 dst2 (opc1 : op src1 dst1) (opc2 : op src2 dst2)
: exprf (var:=ovar) src1
@@ -117,46 +113,19 @@ Section language.
Definition smart_boundf {var t1} (e1 : exprf (var:=var) t1) (bounds : interp_flat_type interp_base_type_bounds t1)
: exprf (var:=var) (bound_flat_type bounds)
:= LetIn e1 (fun e1' => SmartPairf (var:=var) (interpf_smart_bound_exprf e1' bounds)).
- Fixpoint UnSmartArrow {P t}
- : forall (e_bounds : interp_type interp_base_type_bounds t)
- (input_bounds : interp_all_binders_for' t interp_base_type_bounds)
- (e : P (SmartArrow (bound_flat_type input_bounds)
- (bound_flat_type (ApplyInterpedAll' e_bounds input_bounds)))),
- P (bound_type e_bounds input_bounds)
- := match t
- return (forall (e_bounds : interp_type interp_base_type_bounds t)
- (input_bounds : interp_all_binders_for' t interp_base_type_bounds)
- (e : P (SmartArrow (bound_flat_type input_bounds)
- (bound_flat_type (ApplyInterpedAll' e_bounds input_bounds)))),
- P (bound_type e_bounds input_bounds))
- with
- | Tflat T => fun _ _ x => x
- | Arrow A B => fun e_bounds input_bounds
- => @UnSmartArrow
- (fun t => P (Arrow (bound_base_type A (fst input_bounds)) t))
- B
- (e_bounds (fst input_bounds))
- (snd input_bounds)
- end.
Definition smart_bound {var t1} (e1 : expr (var:=var) t1)
(e_bounds : interp_type interp_base_type_bounds t1)
- (input_bounds : interp_all_binders_for' t1 interp_base_type_bounds)
+ (input_bounds : interp_flat_type interp_base_type_bounds (domain t1))
: expr (var:=var) (bound_type e_bounds input_bounds)
- := UnSmartArrow
- e_bounds
- input_bounds
- (SmartAbs
- (fun args
- => LetIn
- args
- (fun args
- => LetIn
- (SmartPairf (interpf_smart_unbound_exprf input_bounds (SmartVarfMap (fun _ => Var) args)))
- (fun v => smart_boundf
- (ApplyAll e1 (interp_all_binders_for_of' v))
- (ApplyInterpedAll' e_bounds input_bounds))))).
+ := Abs
+ (fun args
+ => LetIn
+ (SmartPairf (interpf_smart_unbound_exprf input_bounds (SmartVarfMap (fun _ => Var) args)))
+ (fun v => smart_boundf
+ (invert_Abs e1 v)
+ (e_bounds input_bounds))).
Definition SmartBound {t1} (e : Expr t1)
- (input_bounds : interp_all_binders_for' t1 interp_base_type_bounds)
+ (input_bounds : interp_flat_type interp_base_type_bounds (domain t1))
: Expr (bound_type _ input_bounds)
:= fun var => smart_bound (e var) (interp (@interp_op_bounds) (e _)) input_bounds.
End smart_bound.
diff --git a/src/Reflection/SmartBoundInterp.v b/src/Reflection/SmartBoundInterp.v
index 34824e5ce..7723d98c4 100644
--- a/src/Reflection/SmartBoundInterp.v
+++ b/src/Reflection/SmartBoundInterp.v
@@ -80,7 +80,6 @@ Section language.
= interpf_smart_unbound bounds (SmartVarfMap (fun _ e => interpf interp_op e) e).
Proof. clear -interpf_cast; induction t; t. Qed.
- (*
Lemma interp_smart_bound_and_rel {t}
(e : expr t) (ebounds : expr t)
(Hwf : wf e ebounds)
@@ -142,5 +141,4 @@ Section language.
Proof.
intros; eapply InterpSmartBoundAndRel; auto.
Qed.
- *)
End language.
diff --git a/src/Reflection/SmartBoundWf.v b/src/Reflection/SmartBoundWf.v
index 0b16577d0..6c2846337 100644
--- a/src/Reflection/SmartBoundWf.v
+++ b/src/Reflection/SmartBoundWf.v
@@ -31,8 +31,7 @@ Section language.
Local Notation Expr := (@Expr base_type_code op).
Local Notation SmartBound := (@SmartBound _ _ _ interp_op_bounds bound_base_type Cast).
Local Notation smart_bound := (@smart_bound _ _ interp_base_type_bounds bound_base_type Cast).
- Local Notation UnSmartArrow := (@UnSmartArrow _ interp_base_type_bounds bound_base_type).
- Local Notation interpf_smart_bound := (@interpf_smart_bound _ op interp_base_type_bounds bound_base_type Cast).
+ Local Notation interpf_smart_bound_exprf := (@interpf_smart_bound_exprf _ op interp_base_type_bounds bound_base_type Cast).
Local Notation interpf_smart_unbound_exprf := (@interpf_smart_unbound_exprf _ op interp_base_type_bounds bound_base_type Cast).
Local Notation bound_op := (@bound_op _ _ _ interp_op_bounds bound_base_type _ base_type_bl_transparent base_type_leb Cast genericize_op).
Local Notation wff_SmartCast_match := (@wff_SmartCast_match _ op _ base_type_bl_transparent Cast wff_Cast).
@@ -61,64 +60,6 @@ Section language.
| solve [ auto ] ].
Qed.
- Fixpoint wf_UnSmartArrow {var1 var2} k t1 G e_bounds input_bounds e1 e2
- (Hwf : wf G e1 e2)
- {struct t1}
- : wf G
- (@UnSmartArrow (fun t => @expr base_type_code op var1 (k t)) t1 e_bounds input_bounds e1)
- (@UnSmartArrow (fun t => @expr base_type_code op var2 (k t)) t1 e_bounds input_bounds e2).
- Proof.
- clear -Hwf wf_UnSmartArrow.
- destruct t1 as [t1|s d];
- [ clear wf_UnSmartArrow
- | specialize (wf_UnSmartArrow var1 var2 (fun t => k (Arrow (bound_base_type _ (fst input_bounds)) t)) d G (e_bounds (fst input_bounds)) (snd input_bounds)) ];
- set (e1' := e1); set (e2' := e2);
- let t := match type of Hwf with wf (t:=?t) _ _ _ => t end in
- set (Tt := t) in e1, e2, Hwf;
- pose (eq_refl : Tt = t) as Ht;
- generalize (eq_refl : e1' = match Ht in (_ = y) return expr _ _ y with eq_refl => e1 end);
- generalize (eq_refl : e2' = match Ht in (_ = y) return expr _ _ y with eq_refl => e2 end);
- clearbody Ht; revert Ht;
- clearbody e1' e2'; revert e1' e2';
- clearbody Tt;
- destruct Hwf;
- intros; simpl in *; repeat subst; try discriminate;
- break_innermost_match;
- inversion_type; subst; simpl.
- { constructor; assumption. }
- { constructor; assumption. }
- { apply wf_UnSmartArrow; clear wf_UnSmartArrow.
- match goal with
- | [ |- context[match k ?x with _ => _ end] ]
- => set (kx := k x) in *
- end.
- repeat match goal with
- | [ H : context[k ?x] |- _ ]
- => change (k x) with kx in H
- | [ |- context[k ?x] ]
- => change (k x) with kx
- end.
- destruct kx;
- inversion_type; subst; simpl;
- try tauto;
- try (constructor; assumption). }
- { apply wf_UnSmartArrow; clear wf_UnSmartArrow.
- match goal with
- | [ |- context[match k ?x with _ => _ end] ]
- => set (kx := k x) in *
- end.
- repeat match goal with
- | [ H : context[k ?x] |- _ ]
- => change (k x) with kx in H
- | [ |- context[k ?x] ]
- => change (k x) with kx
- end.
- destruct kx;
- inversion_type; break_innermost_match; subst; simpl;
- try tauto;
- try (constructor; assumption). }
- Qed.
-
Local Hint Resolve List.in_app_or List.in_or_app.
Lemma wff_SmartPairf_interpf_smart_unbound_exprf var1 var2 t input_bounds x1 x2
@@ -149,23 +90,41 @@ Section language.
Local Hint Resolve wff_SmartPairf_interpf_smart_unbound_exprf : wf.
- Axiom proof_admitted : False.
+ Lemma wff_SmartPairf_interpf_smart_bound_exprf var1 var2 t x1 x2 output_bounds
+ : wff (flatten_binding_list x1 x2)
+ (SmartPairf
+ (var:=var1)
+ (interpf_smart_bound_exprf (t:=t) x1 output_bounds))
+ (SmartPairf
+ (var:=var2)
+ (interpf_smart_bound_exprf x2 output_bounds)).
+ Proof.
+ clear -wff_Cast.
+ unfold SmartPairf, SmartVarfMap, interpf_smart_bound_exprf; induction t;
+ repeat match goal with
+ | _ => progress simpl in *
+ | [ |- wff _ (Cast _ _ _ _) (Cast _ _ _ _) ]
+ => apply wff_Cast
+ | [ |- wff _ _ _ ]
+ => constructor
+ | _ => solve [ auto with wf ]
+ | _ => eapply wff_in_impl_Proper; [ solve [ eauto ] | ]
+ | _ => intro
+ end.
+ Qed.
+
+ Local Hint Resolve wff_SmartPairf_interpf_smart_bound_exprf : wf.
- Lemma wf_smart_bound {var1 var2 t1} G e1 e2 e_bounds input_bounds
- (Hwf : wf G e1 e2)
- : wf G
- (@smart_bound var1 t1 e1 e_bounds input_bounds)
+ Lemma wf_smart_bound {var1 var2 t1} e1 e2 e_bounds input_bounds
+ (Hwf : wf e1 e2)
+ : wf (@smart_bound var1 t1 e1 e_bounds input_bounds)
(@smart_bound var2 t1 e2 e_bounds input_bounds).
Proof.
clear -wff_Cast Hwf.
- unfold SmartBound.smart_bound.
- apply wf_UnSmartArrow with (k:=fun x => x).
- apply wf_SmartAbs; intros.
- repeat constructor; auto with wf;
+ destruct Hwf; unfold SmartBound.smart_bound.
+ repeat constructor; auto with wf; intros;
try (eapply wff_in_impl_Proper; [ solve [ eauto with wf ] | ]);
auto.
- { case proof_admitted. }
- { case proof_admitted. }
Qed.
Lemma Wf_SmartBound {t1} e input_bounds
diff --git a/src/Reflection/SmartMap.v b/src/Reflection/SmartMap.v
index c18b2b8fb..5cddc0418 100644
--- a/src/Reflection/SmartMap.v
+++ b/src/Reflection/SmartMap.v
@@ -24,7 +24,6 @@ Section homogenous_type.
another kind, and simultaneously mapping a function over the
base values (e.g., [Var] (for turning [var] into [exprf]) or
[Const] (for turning [interp_base_type] into [exprf])). *)
-
Fixpoint smart_interp_flat_map {f g}
(h : forall x, f x -> g (Tbase x))
(tt : g Unit)
@@ -51,58 +50,23 @@ Section homogenous_type.
(@smart_interp_flat_map2 f1 f2 g h tt pair A (fst v1) (fst v2))
(@smart_interp_flat_map2 f1 f2 g h tt pair B (snd v1) (snd v2))
end.
- Fixpoint smart_interp_map_hetero {f g g'}
- (h : forall x, f x -> g (Tflat (Tbase x)))
- (tt : g Unit)
- (pair : forall A B, g (Tflat A) -> g (Tflat B) -> g (Prod A B))
- (abs : forall A B, (g' A -> g B) -> g (Arrow A B))
- {t}
- : interp_type_gen_hetero g' (interp_flat_type f) t -> g t
- := match t return interp_type_gen_hetero g' (interp_flat_type f) t -> g t with
- | Tflat _ => @smart_interp_flat_map f (fun x => g (Tflat x)) h tt pair _
- | Arrow A B => fun v => abs _ _
- (fun x => @smart_interp_map_hetero f g g' h tt pair abs B (v x))
- end.
- Fixpoint smart_interp_map_gen {f g}
- (h : forall x, f x -> g (Tflat (Tbase x)))
- (h' : forall x, g (Tflat (Tbase x)) -> f x)
- (flat_map : forall t, interp_flat_type f t -> g t)
- (abs : forall A B, (g (Tflat (Tbase A)) -> g B) -> g (Arrow A B))
- {t}
- : interp_type_gen (interp_flat_type f) t -> g t
- := match t return interp_type_gen (interp_flat_type f) t -> g t with
- | Tflat T => flat_map T
- | Arrow A B => fun v => abs _ _
- (fun x => @smart_interp_map_gen f g h h' flat_map abs B (v (h' _ x)))
- end.
- Definition smart_interp_map {f g}
- (h : forall x, f x -> g (Tflat (Tbase x)))
- (h' : forall x, g (Tflat (Tbase x)) -> f x)
+ Definition smart_interp_map_hetero {f g g'}
+ (h : forall x, f x -> g (Tbase x))
(tt : g Unit)
- (pair : forall A B, g (Tflat A) -> g (Tflat B) -> g (Prod A B))
- (abs : forall A B, (g (Tflat (Tbase A)) -> g B) -> g (Arrow A B))
+ (pair : forall A B, g A -> g B -> g (Prod A B))
+ (abs : forall A B, (g A -> g B) -> g' (Arrow A B))
{t}
- : interp_type_gen (interp_flat_type f) t -> g t
- := @smart_interp_map_gen f g h h' (@smart_interp_flat_map f (fun x => g (Tflat x)) h tt pair) abs t.
+ : interp_type_gen_hetero g (interp_flat_type f) t -> g' t
+ := match t return interp_type_gen_hetero g (interp_flat_type f) t -> g' t with
+ | Arrow A B => fun v => abs _ _
+ (fun x => @smart_interp_flat_map f g h tt pair _ (v x))
+ end.
Fixpoint SmartValf {T} (val : forall t : base_type_code, T t) t : interp_flat_type T t
:= match t return interp_flat_type T t with
| Syntax.Tbase _ => val _
| Unit => tt
| Prod A B => (@SmartValf T val A, @SmartValf T val B)
end.
- Fixpoint SmartArrow (A : flat_type) (B : type) : type
- := match A with
- | Syntax.Tbase A' => Arrow A' B
- | Unit => B
- | Prod A0 A1
- => SmartArrow A0 (SmartArrow A1 B)
- end.
- Fixpoint SmartAbs {A B} {struct A} : forall (f : exprf A -> expr B), expr (SmartArrow A B)
- := match A return (exprf A -> expr B) -> expr (SmartArrow A B) with
- | Syntax.Tbase x => fun f => Abs (fun x => f (Var x))
- | Unit => fun f => f TT
- | Prod x y => fun f => @SmartAbs x _ (fun x' => @SmartAbs y _ (fun y' => f (Pair x' y')))
- end.
(** [SmartVar] is like [Var], except that it inserts
pair-projections and [Pair] as necessary to handle [flat_type],
@@ -209,12 +173,13 @@ Section homogenous_type.
| Prod A B => fun v xy => (@SmartFlatTypeMapUnInterp _ _ _ f fv A _ (fst xy),
@SmartFlatTypeMapUnInterp _ _ _ f fv B _ (snd xy))
end.
- Definition SmartVarMap {var var'} (f : forall t, var t -> var' t) (f' : forall t, var' t -> var t) {t}
- : interp_type_gen (interp_flat_type var) t -> interp_type_gen (interp_flat_type var') t
- := @smart_interp_map var (interp_type_gen (interp_flat_type var')) f f' tt (fun A B x y => pair x y) (fun A B f x => f x) t.
- Definition SmartVarMap_hetero {vars vars' var var'} (f : forall t, var t -> var' t) (f' : forall t, vars' t -> vars t) {t}
- : interp_type_gen_hetero vars (interp_flat_type var) t -> interp_type_gen_hetero vars' (interp_flat_type var') t
- := @smart_interp_map_hetero var (interp_type_gen_hetero vars' (interp_flat_type var')) vars f tt (fun A B x y => pair x y) (fun A B f x => f (f' _ x)) t.
+ Definition SmartVarMap {var' var''} (f : forall t, var' t -> var'' t) (f' : forall t, var'' t -> var' t) {t}
+ : interp_type_gen (interp_flat_type var') t -> interp_type_gen (interp_flat_type var'') t
+ := match t return interp_type_gen (interp_flat_type var') t -> interp_type_gen (interp_flat_type var'') t with
+ | Arrow src dst => fun F x => SmartVarfMap f (F (SmartVarfMap f' x))
+ end.
+ Lemma SmartVarMap_id {var' t} x v : @SmartVarMap var' var' (fun _ x => x) (fun _ x => x) t x v = x v.
+ Proof. destruct t; simpl; rewrite !SmartVarfMap_id; reflexivity. Qed.
Definition SmartVarVarf {t} : interp_flat_type var t -> interp_flat_type exprfb t
:= SmartVarfMap (fun t => Var).
End homogenous_type.
@@ -233,9 +198,7 @@ Global Arguments SmartFlatTypeMap {_ _} _ {_} _.
Global Arguments SmartFlatTypeUnMap {_} _.
Global Arguments SmartFlatTypeMapInterp {_ _ _ _} _ {_} _.
Global Arguments SmartFlatTypeMapUnInterp {_ _ _ _ _} fv {_ _} _.
-Global Arguments SmartVarMap_hetero {_ _ _ _ _} _ _ {_} _.
Global Arguments SmartVarMap {_ _ _} _ _ {!_} _ / .
-Global Arguments SmartAbs {_ _ _ _ _} _.
Section hetero_type.
Fixpoint flatten_flat_type {base_type_code} (t : flat_type (flat_type base_type_code)) : flat_type base_type_code
diff --git a/src/Reflection/Syntax.v b/src/Reflection/Syntax.v
index ee60265e0..d77731633 100644
--- a/src/Reflection/Syntax.v
+++ b/src/Reflection/Syntax.v
@@ -16,10 +16,9 @@ Section language.
Inductive flat_type := Tbase (T : base_type_code) | Unit | Prod (A B : flat_type).
Bind Scope ctype_scope with flat_type.
- Inductive type := Tflat (T : flat_type) | Arrow (A : base_type_code) (B : type).
+ Inductive type := Arrow (A : flat_type) (B : flat_type).
Bind Scope ctype_scope with type.
- Global Coercion Tflat : flat_type >-> type.
Infix "*" := Prod : ctype_scope.
Notation "A -> B" := (Arrow A B) : ctype_scope.
Local Coercion Tbase : base_type_code >-> flat_type.
@@ -38,20 +37,16 @@ Section language.
end.
End tuple.
+ Definition domain (t : type) : flat_type
+ := match t with Arrow src dst => src end.
+ Definition codomain (t : type) : flat_type
+ := match t with Arrow src dst => dst end.
+
Section interp.
- Section type.
- Section hetero.
- Context (interp_src_type : base_type_code -> Type).
- Context (interp_flat_type : flat_type -> Type).
- Fixpoint interp_type_gen_hetero (t : type) :=
- match t with
- | Tflat t => interp_flat_type t
- | Arrow x y => (interp_src_type x -> interp_type_gen_hetero y)%type
- end.
- End hetero.
- Definition interp_type_gen (interp_flat_type : flat_type -> Type)
- := interp_type_gen_hetero interp_flat_type interp_flat_type.
- End type.
+ Definition interp_type_gen_hetero (interp_src interp_dst : flat_type -> Type) (t : type) :=
+ (interp_src match t with Arrow x y => x end -> interp_dst match t with Arrow x y => y end)%type.
+ Definition interp_type_gen (interp_flat_type : flat_type -> Type)
+ := interp_type_gen_hetero interp_flat_type interp_flat_type.
Section flat_type.
Context (interp_base_type : base_type_code -> Type).
Fixpoint interp_flat_type (t : flat_type) :=
@@ -82,10 +77,8 @@ Section language.
| Pair {tx} (ex : exprf tx) {ty} (ey : exprf ty) : exprf (Prod tx ty).
Bind Scope expr_scope with exprf.
Inductive expr : type -> Type :=
- | Return {t} (ex : exprf t) : expr t
- | Abs {src dst} (f : var src -> expr dst) : expr (Arrow src dst).
+ | Abs {src dst} (f : interp_flat_type_gen var src -> exprf dst) : expr (Arrow src dst).
Bind Scope expr_scope with expr.
- Global Coercion Return : exprf >-> expr.
End expr.
Definition Expr (t : type) := forall var, @expr var t.
@@ -107,11 +100,16 @@ Section language.
Fixpoint interpf {t} e
:= @interpf_step (@interpf) t e.
- Fixpoint interp {t} (e : @expr interp_type t) : interp_type t
- := match e in expr t return interp_type t with
- | Return _ x => interpf x
- | Abs _ _ f => fun x => @interp _ (f x)
- end.
+ Definition interp {t} (e : @expr interp_base_type t) : interp_type t
+ := fun x
+ => @interpf
+ _
+ (match e in @expr _ t
+ return interp_flat_type (domain t)
+ -> exprf (codomain t)
+ with
+ | Abs _ _ f => f
+ end x).
Definition Interp {t} (E : Expr t) : interp_type t := interp (E _).
End interp.
@@ -123,14 +121,14 @@ Global Arguments Unit {_}%type_scope.
Global Arguments Prod {_}%type_scope (_ _)%ctype_scope.
Global Arguments Arrow {_}%type_scope (_ _)%ctype_scope.
Global Arguments Tbase {_}%type_scope _%ctype_scope.
-Global Arguments Tflat {_}%type_scope _%ctype_scope.
+Global Arguments domain {_}%type_scope _%ctype_scope.
+Global Arguments codomain {_}%type_scope _%ctype_scope.
Global Arguments Var {_ _ _ _} _.
Global Arguments TT {_ _ _}.
Global Arguments Op {_ _ _ _ _} _ _.
Global Arguments LetIn {_ _ _ _} _ {_} _.
Global Arguments Pair {_ _ _ _} _ {_} _.
-Global Arguments Return {_ _ _ _} _.
Global Arguments Abs {_ _ _ _ _} _.
Global Arguments interp_type_gen_hetero {_} _ _ _.
Global Arguments interp_type_gen {_} _ _.
@@ -139,6 +137,7 @@ Global Arguments interp_type {_} _ _.
Global Arguments Interp {_ _ _} interp_op {t} _.
Global Arguments interp {_ _ _} interp_op {t} _.
Global Arguments interpf {_ _ _} interp_op {t} _.
+Global Arguments interp _ _ _ _ _ !_ / .
Module Export Notations.
Notation "()" := (@Unit _) : ctype_scope.
diff --git a/src/Reflection/TestCase.v b/src/Reflection/TestCase.v
index c4287239e..3cbe70594 100644
--- a/src/Reflection/TestCase.v
+++ b/src/Reflection/TestCase.v
@@ -60,17 +60,26 @@ Goal (flat_type base_type -> Type) -> False.
let x := reifyf base_type interp_base_type op var (1 + 1)%nat in pose x.
let x := Reify' (1 + 1)%nat in unify x (fun var => Return (Op Add (Pair (InputSyntax.Const (interp_base_type:=interp_base_type) (var:=var) (t:=Tbase Tnat) (op:=op) 1) (InputSyntax.Const (interp_base_type:=interp_base_type) (var:=var) (t:=Tbase Tnat) (op:=op) 1)))).
let x := reify_abs base_type interp_base_type op var (fun x => x + 1)%nat in pose x.
- let x := Reify' (fun x => x + 1)%nat in unify x (fun var => Abs (fun y => Op Add (Pair (Var y) (InputSyntax.Const (interp_base_type:=interp_base_type) (var:=var) (t:=Tbase Tnat) (op:=op) 1)))).
+ let x := Reify' (fun x => x + 1)%nat in unify x (fun var => Abs (fun y => Return (Op Add (Pair (Var y) (InputSyntax.Const (interp_base_type:=interp_base_type) (var:=var) (t:=Tbase Tnat) (op:=op) 1))))).
let x := reifyf base_type interp_base_type op var (let '(a, b) := (1, 1) in a + b)%nat in pose x.
let x := reifyf base_type interp_base_type op var (let '(a, b, c) := (1, 1, 1) in a + b + c)%nat in pose x.
let x := Reify' (fun x => let '(a, b) := (1, 1) in a + x)%nat in let x := (eval vm_compute in x) in pose x.
+ let x := Reify' (fun x => let '(a, b, c, (d, e), f) := x in a + b + c + d + e + f)%nat in let x := (eval vm_compute in x) in pose x.
+ let x := Reify' (fun x => let '(a, b) := x in let '(a, c) := a in let '(a, d) := a in a + b + c + d)%nat in let x := (eval vm_compute in x) in pose x.
+ let x := Reify' (fun ab0 : nat * nat * nat * nat => let (f, g6) := fst ab0 in
+ let (f0, g7) := f in
+ let ab3 := (1, 1) in
+ let ab21 := (1, 1) in
+ let z := snd ab3 + snd ab21 in z + z)%nat in let x := (eval vm_compute in x) in pose x.
+ let x := Reify' (fun ab0 : nat * nat * nat => let (f, g7) := fst ab0 in 1 + 1) in let x := (eval vm_compute in x) in pose x.
let x := Reify' (fun x => let '(a, b) := (1, 1) in a + x)%nat in
unify x (fun var => Abs (fun x' =>
let c1 := (InputSyntax.Const (interp_base_type:=interp_base_type) (var:=var) (t:=Tbase Tnat) (op:=op) 1) in
- MatchPair (tC:=tnat) (Pair c1 c1)
- (fun x0 _ : var tnat => Op Add (Pair (Var x0) (Var x'))))).
+ Return (MatchPair (tC:=tnat) (Pair c1 c1)
+ (fun x0 y0 : var tnat => Op Add (Pair (Var x0) (Var x')))))).
let x := reifyf base_type interp_base_type op var (let x := 5 in let y := 6 in (let a := 1 in let '(c, d) := (2, 3) in a + x + c + d) + y)%nat in pose x.
- let x := Reify' (fun x y => (let a := 1 in let '(c, d) := (2, 3) in a + x + c + d) + y)%nat in pose x.
+ let x := Reify' (let x := 1 in let y := 1 in (let a := 1 in let '(c, d) := (2, 3) in a + x + c + d) + y)%nat in pose x.
+ let x := Reify' (fun xy => let '(x, y) := xy in (let a := 1 in let '(c, d) := (2, 3) in a + x + c + d) + y)%nat in pose x.
Abort.
@@ -85,14 +94,14 @@ Abort.
Import Linearize Inline.
Goal True.
- let x := Reify (fun x y => (let a := 1 in let '(c, d) := (2, 3) in a + x - a + c + d) + y)%nat in
+ let x := Reify (fun xy => let '(x, y) := xy in (let a := 1 in let '(c, d) := (2, 3) in a + x - a + c + d) + y)%nat in
pose (InlineConst is_const (Linearize x)) as e.
vm_compute in e.
Abort.
-Definition example_expr : Syntax.Expr base_type op (Arrow Tnat (Arrow Tnat (Tflat tnat))).
+Definition example_expr : Syntax.Expr base_type op (Syntax.Arrow (tnat * tnat) tnat).
Proof.
- let x := Reify (fun z w => let unused := 1 + 1 in let x := 1 in let y := 1 in (let a := 1 in let '(c, d) := (2, 3) in a + x + (x + x) + (x + x) - (x + x) - a + c + d) + y + z + w)%nat in
+ let x := Reify (fun zw => let '(z, w) := zw in let unused := 1 + 1 in let x := 1 in let y := 1 in (let a := 1 in let '(c, d) := (2, 3) in a + x + (x + x) + (x + x) - (x + x) - a + c + d) + y + z + w)%nat in
exact x.
Defined.
@@ -138,7 +147,7 @@ Lemma example_expr_wf_slow : Wf example_expr.
Proof.
Time (vm_compute; intros;
repeat match goal with
- | [ |- wf _ _ _ ] => constructor; intros
+ | [ |- wf _ _ ] => constructor; intros
| [ |- wff _ _ _ ] => constructor; intros
| [ |- List.In _ _ ] => vm_compute
| [ |- ?x = ?x \/ _ ] => left; reflexivity
@@ -222,6 +231,6 @@ Module bounds.
end.
Compute (fun x xpf y ypf => proj1_sig (Syntax.Interp interp_op_bounds example_expr
- (exist _ {| lower := 0 ; value := x ; upper := 10 |} xpf)
- (exist _ {| lower := 100 ; value := y ; upper := 1000 |} ypf))).
+ (exist _ {| lower := 0 ; value := x ; upper := 10 |} xpf,
+ exist _ {| lower := 100 ; value := y ; upper := 1000 |} ypf))).
End bounds.
diff --git a/src/Reflection/TypeInversion.v b/src/Reflection/TypeInversion.v
index 8a10a36a8..7d0999061 100644
--- a/src/Reflection/TypeInversion.v
+++ b/src/Reflection/TypeInversion.v
@@ -49,23 +49,12 @@ Section language.
Definition preinvert_Arrow (P : type base_type_code -> Type) (Q : forall A B, P (Arrow A B) -> Type)
: (forall t (p : P t), match t return P t -> Type with
| Arrow A B => Q A B
- | _ => fun _ => True
end p)
-> forall A B p, Q A B p.
Proof.
intros H A B p; specialize (H _ p); assumption.
Defined.
- Definition preinvert_Tflat (P : type base_type_code -> Type) (Q : forall T, P (Tflat T) -> Type)
- : (forall t (p : P t), match t return P t -> Type with
- | Tflat T => Q T
- | _ => fun _ => True
- end p)
- -> forall T p, Q T p.
- Proof.
- intros H T p; specialize (H _ p); assumption.
- Defined.
-
Section encode_decode.
Definition flat_type_code (t1 t2 : flat_type base_type_code) : Prop
:= match t1, t2 with
@@ -79,13 +68,7 @@ Section language.
end.
Definition type_code (t1 t2 : type base_type_code) : Prop
- := match t1, t2 with
- | Tflat t1, Tflat t2 => t1 = t2
- | Arrow A B, Arrow A' B' => A = A' /\ B = B'
- | Tflat _, _
- | Arrow _ _, _
- => False
- end.
+ := domain t1 = domain t2 /\ codomain t1 = codomain t2.
Definition flat_type_encode (x y : flat_type base_type_code) : x = y -> flat_type_code x y.
Proof. intro p; destruct p, x; repeat constructor. Defined.
@@ -151,11 +134,6 @@ Ltac preinvert_one_type e :=
| ?P Unit
=> revert dependent e;
refine (preinvert_Unit P _ _)
- | ?P (Tflat ?T)
- => is_var T;
- move e at top;
- revert dependent T;
- refine (preinvert_Tflat P _ _)
| ?P (Arrow ?A ?B)
=> is_var A; is_var B;
move e at top; revert dependent A; intros A e;
@@ -192,10 +170,6 @@ Ltac inversion_flat_type := repeat inversion_flat_type_step.
Ltac inversion_type_step :=
lazymatch goal with
- | [ H : _ = Tflat _ |- _ ]
- => induction_type_in_using H @path_type_rect
- | [ H : Tflat _ = _ |- _ ]
- => induction_type_in_using H @path_type_rect
| [ H : _ = Arrow _ _ |- _ ]
=> induction_type_in_using H @path_type_rect
| [ H : Arrow _ _ = _ |- _ ]
diff --git a/src/Reflection/Wf.v b/src/Reflection/Wf.v
index 3b48853c6..91a99b150 100644
--- a/src/Reflection/Wf.v
+++ b/src/Reflection/Wf.v
@@ -50,14 +50,13 @@ Section language.
wff G e1 e1'
-> wff G e2 e2'
-> wff G (Pair e1 e2) (Pair e1' e2').
- Inductive wf : list (sigT eP) -> forall {t}, @expr var1 t -> @expr var2 t -> Prop :=
- | WfReturn : forall t G e e', @wff G t e e' -> wf G (Return e) (Return e')
- | WfAbs : forall A B G e e',
- (forall x x', @wf ((x == x') :: G) B (e x) (e' x'))
- -> @wf G (Arrow A B) (Abs e) (Abs e').
+ Inductive wf : forall {t}, @expr var1 t -> @expr var2 t -> Prop :=
+ | WfAbs : forall A B e e',
+ (forall x x', @wff (flatten_binding_list x x') B (e x) (e' x'))
+ -> @wf (Arrow A B) (Abs e) (Abs e').
End with_var.
- Definition Wf {t} (E : @Expr t) := forall var1 var2, wf nil (E var1) (E var2).
+ Definition Wf {t} (E : @Expr t) := forall var1 var2, wf (E var1) (E var2).
Axiom Wf_admitted : forall {t} (E:Expr t), @Wf t E.
End language.
@@ -65,7 +64,7 @@ End language.
Ltac admit_Wf := apply Wf_admitted.
Global Arguments wff {_ _ _ _} G {t} _ _.
-Global Arguments wf {_ _ _ _} G {t} _ _.
+Global Arguments wf {_ _ _ _ t} _ _.
Global Arguments Wf {_ _ t} _.
Hint Constructors wf wff : wf.
diff --git a/src/Reflection/WfInversion.v b/src/Reflection/WfInversion.v
index cdaa7ffb5..111c8a4a4 100644
--- a/src/Reflection/WfInversion.v
+++ b/src/Reflection/WfInversion.v
@@ -132,6 +132,40 @@ Section language.
end;
t.
Qed.
+
+ Definition wf_code {t} (e1 : @expr var1 t) : forall (e2 : @expr var2 t), Prop
+ := match e1 in Syntax.expr _ _ t return expr t -> Prop with
+ | Abs src dst f1
+ => fun e2
+ => let f2 := invert_Abs e2 in
+ forall (x : interp_flat_type var1 src) (x' : interp_flat_type var2 src),
+ wff (flatten_binding_list x x') (f1 x) (f2 x')
+ end.
+
+ Definition wf_encode {t e1 e2} (v : @wf var1 var2 t e1 e2) : @wf_code t e1 e2.
+ Proof.
+ destruct v; t.
+ Defined.
+
+ Definition wf_decode {t e1 e2} (v : @wf_code t e1 e2) : @wf var1 var2 t e1 e2.
+ Proof.
+ destruct e1; t.
+ Defined.
+
+ Definition wf_endecode {t e1 e2} v : @wf_decode t e1 e2 (@wf_encode t e1 e2 v) = v.
+ Proof.
+ destruct v; reflexivity.
+ Qed.
+
+ Definition wf_deencode {t e1 e2} v : @wf_encode t e1 e2 (@wf_decode t e1 e2 v) = v.
+ Proof.
+ destruct e1 as [src dst f1].
+ revert dependent f1.
+ refine match e2 with
+ | Abs _ _ f2 => _
+ end.
+ reflexivity.
+ Qed.
End with_var.
End language.
@@ -143,12 +177,11 @@ Ltac is_expr_constructor arg :=
| LetIn _ _ => idtac
| Pair _ _ => idtac
| Abs _ => idtac
- | Return _ => idtac
end.
-Ltac inversion_wff_step_gen guard_tac :=
+Ltac inversion_wf_step_gen guard_tac :=
let postprocess H :=
- (cbv [wff_code] in H;
+ (cbv [wff_code wf_code] in H;
simpl in H;
try match type of H with
| True => clear H
@@ -158,11 +191,14 @@ Ltac inversion_wff_step_gen guard_tac :=
| [ H : wff _ ?x ?y |- _ ]
=> guard_tac x y;
apply wff_encode in H; postprocess H
+ | [ H : wf ?x ?y |- _ ]
+ => guard_tac x y;
+ apply wf_encode in H; postprocess H
end.
-Ltac inversion_wff_step_constr :=
- inversion_wff_step_gen ltac:(fun x y => is_expr_constructor x; is_expr_constructor y).
-Ltac inversion_wff_step_var :=
- inversion_wff_step_gen ltac:(fun x y => first [ is_var x; is_var y; fail 1 | idtac ]).
-Ltac inversion_wff_step := first [ inversion_wff_step_constr | inversion_wff_step_var ].
-Ltac inversion_wff_constr := repeat inversion_wff_step_constr.
-Ltac inversion_wff := repeat inversion_wff_step.
+Ltac inversion_wf_step_constr :=
+ inversion_wf_step_gen ltac:(fun x y => is_expr_constructor x; is_expr_constructor y).
+Ltac inversion_wf_step_var :=
+ inversion_wf_step_gen ltac:(fun x y => first [ is_var x; is_var y; fail 1 | idtac ]).
+Ltac inversion_wf_step := first [ inversion_wf_step_constr | inversion_wf_step_var ].
+Ltac inversion_wf_constr := repeat inversion_wf_step_constr.
+Ltac inversion_wf := repeat inversion_wf_step.
diff --git a/src/Reflection/WfProofs.v b/src/Reflection/WfProofs.v
index 937d53533..2b9197858 100644
--- a/src/Reflection/WfProofs.v
+++ b/src/Reflection/WfProofs.v
@@ -117,23 +117,9 @@ Section language.
| _ => progress simpl in *
| _ => progress destruct_head' or
| _ => solve [ eauto with nocore ]
- | _ => progress inversion_wff
+ | _ => progress inversion_wf
end.
Qed.
-
- Lemma wf_SmartAbs {A B} G e1 e2
- (Hwf : forall G' x y, wff (G' ++ G) x y -> wf (G' ++ G) (e1 x) (e2 y))
- : @wf _ op var1 var2 G _ (@SmartAbs _ _ _ A B e1) (@SmartAbs _ _ _ A B e2).
- Proof.
- revert dependent G; revert dependent B; induction A; intros.
- { simpl; constructor; intros.
- apply (Hwf (_::nil)%list); constructor; left; reflexivity. }
- { apply (Hwf nil); constructor. }
- { simpl in *.
- do 2 match goal with H : _ |- _ => apply H; intros end.
- rewrite List.app_assoc; apply Hwf; rewrite <- List.app_assoc.
- eauto with wf. }
- Qed.
End with_var.
Definition duplicate_type {var1 var2}
diff --git a/src/Reflection/WfReflective.v b/src/Reflection/WfReflective.v
index da731d511..aafe67c84 100644
--- a/src/Reflection/WfReflective.v
+++ b/src/Reflection/WfReflective.v
@@ -50,6 +50,7 @@
Require Import Coq.Arith.Arith Coq.Logic.Eqdep_dec.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.Wf.
+Require Import Crypto.Reflection.EtaWf.
Require Import Crypto.Reflection.WfReflectiveGen.
Require Import Crypto.Util.Notations Crypto.Util.Tactics Crypto.Util.Option Crypto.Util.Sigma Crypto.Util.Prod Crypto.Util.Decidable Crypto.Util.ListUtil.
Require Export Crypto.Util.PartiallyReifiedProp. (* export for the [bool >-> reified_Prop] coercion *)
@@ -136,8 +137,10 @@ Section language.
| [ H : List.In _ (duplicate_type _) |- _ ] => eapply duplicate_type_in in H; [ | eassumption.. ]
| [ H : context[match _ with _ => _ end] |- _ ] => revert H; progress break_innermost_match
| [ |- wff _ _ _ ] => constructor
- | [ |- wf _ _ _ ] => constructor
+ | [ |- wf _ _ ] => constructor
| _ => progress unfold and_reified_Prop in *
+ | [ |- wff (flatten_binding_list ?x ?y) _ _ ]
+ => rewrite <- (List.app_nil_r (flatten_binding_list x y))
end.
Local Ltac t := repeat t_step.
Fixpoint reflect_wff (G : list (sigT (fun t => var1 t * var2 t)%type))
@@ -177,33 +180,29 @@ Section language.
{ t. }
{ t. }
Qed.
- Fixpoint reflect_wf (G : list (sigT (fun t => var1 t * var2 t)%type))
+ Definition reflect_wf
{t1 t2 : type}
(e1 : @expr (fun t => nat * var1 t)%type t1) (e2 : @expr (fun t => nat * var2 t)%type t2)
- : let reflective_obligation := reflect_wfT (duplicate_type G) e1 e2 in
+ : let reflective_obligation := reflect_wfT nil e1 e2 in
match type_eq_semidec_transparent t1 t2 with
| Some p
=> to_prop reflective_obligation
- -> @wf base_type_code op var1 var2 G t2 (eq_rect _ expr (unnatize_expr (List.length G) e1) _ p) (unnatize_expr (List.length G) e2)
+ -> @wf base_type_code op var1 var2 t2 (eq_rect _ expr (unnatize_expr 0 e1) _ p) (unnatize_expr 0 e2)
| None => True
end.
Proof.
- destruct e1 as [ t1 e1 | tx tR f ],
- e2 as [ t2 e2 | tx' tR' f' ]; simpl; try solve [ exact I ];
- [ clear reflect_wf;
- pose proof (@reflect_wff G t1 t2 e1 e2)
- | pose proof (fun x x'
- => match preflatten_binding_list2 (Tbase tx) (Tbase tx') as v return match v with Some _ => _ | None => True end with
- | Some G0
- => reflect_wf
- (G0 x x' ++ G)%list _ _
- (f (snd (natize_interp_flat_type (length (duplicate_type G)) x)))
- (f' (snd (natize_interp_flat_type (length (duplicate_type G)) x')))
- | None => I
- end);
- clear reflect_wf ].
- { t. }
- { t. }
+ destruct e1 as [ tx tR f ],
+ e2 as [ tx' tR' f' ]; simpl; try solve [ exact I ].
+ pose proof (fun x x'
+ => match preflatten_binding_list2 tx tx' as v return match v with Some _ => _ | None => True end with
+ | Some G0
+ => reflect_wff
+ (G0 x x' ++ nil)%list
+ (f (snd (natize_interp_flat_type 0 x)))
+ (f' (snd (natize_interp_flat_type 0 x')))
+ | None => I
+ end).
+ t.
Qed.
End language.
@@ -224,7 +223,7 @@ Section Wf.
-> Wf (fun var => unnatize_expr 0 (e (fun t => (nat * var t)%type))).
Proof.
intros H var1 var2; specialize (H var1 var2).
- pose proof (@reflect_wf base_type_code base_type_eq_semidec_transparent base_type_eq_semidec_is_dec op op_beq op_beq_bl var1 var2 nil t t (e _) (e _)) as H'.
+ pose proof (@reflect_wf base_type_code base_type_eq_semidec_transparent base_type_eq_semidec_is_dec op op_beq op_beq_bl var1 var2 t t (e _) (e _)) as H'.
rewrite type_eq_semidec_transparent_refl in H' by assumption; simpl in *.
edestruct @reflect_wfT; simpl in *; tauto.
Qed.
@@ -243,7 +242,13 @@ Section Wf.
Qed.
End Wf.
-
+(** Using [ExprEta'] ensures that reduction and conversion don't block
+ on destructuring the variable arguments. *)
+Ltac preapply_eta'_Wf :=
+ lazymatch goal with
+ | [ |- @Wf ?base_type_code ?op ?t ?e ]
+ => apply (proj1 (@Wf_ExprEta'_iff base_type_code op t e))
+ end.
Ltac generalize_reflect_Wf base_type_eq_semidec_is_dec op_beq_bl :=
lazymatch goal with
| [ |- @Wf ?base_type_code ?op ?t ?e ]
@@ -268,5 +273,6 @@ Ltac fin_reflect_Wf :=
(** The tactic [reflect_Wf] is the main tactic of this file, used to
prove [Syntax.Wf] goals *)
Ltac reflect_Wf base_type_eq_semidec_is_dec op_beq_bl :=
+ preapply_eta'_Wf;
generalize_reflect_Wf base_type_eq_semidec_is_dec op_beq_bl;
use_reflect_Wf; fin_reflect_Wf.
diff --git a/src/Reflection/WfReflectiveGen.v b/src/Reflection/WfReflectiveGen.v
index d4c0b45d0..0e745f059 100644
--- a/src/Reflection/WfReflectiveGen.v
+++ b/src/Reflection/WfReflectiveGen.v
@@ -109,18 +109,13 @@ Section language.
end
| Prod _ _, _ => None
end.
- Fixpoint type_eq_semidec_transparent (t1 t2 : type) : option (t1 = t2)
+ Definition type_eq_semidec_transparent (t1 t2 : type) : option (t1 = t2)
:= match t1, t2 return option (t1 = t2) with
- | Syntax.Tflat t1, Syntax.Tflat t2
- => option_map (@f_equal _ _ (@Tflat _) _ _)
- (flat_type_eq_semidec_transparent t1 t2)
- | Syntax.Tflat _, _ => None
| Arrow A B, Arrow A' B'
- => match base_type_eq_semidec_transparent A A', type_eq_semidec_transparent B B' with
- | Some p, Some q => Some (f_equal2 (@Arrow base_type_code) p q)
- | _, _ => None
- end
- | Arrow _ _, _ => None
+ => match flat_type_eq_semidec_transparent A A', flat_type_eq_semidec_transparent B B' with
+ | Some p, Some q => Some (f_equal2 (@Arrow base_type_code) p q)
+ | _, _ => None
+ end
end.
Lemma base_type_eq_semidec_transparent_refl t : base_type_eq_semidec_transparent t t = Some eq_refl.
Proof.
@@ -139,11 +134,10 @@ Section language.
Lemma type_eq_semidec_transparent_refl t : type_eq_semidec_transparent t t = Some eq_refl.
Proof.
clear -base_type_eq_semidec_is_dec.
- induction t as [t | A B IHt]; simpl.
- { rewrite flat_type_eq_semidec_transparent_refl; reflexivity. }
- { rewrite base_type_eq_semidec_transparent_refl; rewrite_hyp !*; reflexivity. }
+ destruct t; simpl; rewrite !flat_type_eq_semidec_transparent_refl; reflexivity.
Qed.
+
Definition op_beq' t1 tR t1' tR' (x : op t1 tR) (y : op t1' tR') : reified_Prop
:= match flat_type_eq_semidec_transparent t1 t1', flat_type_eq_semidec_transparent tR tR' with
| Some p, Some q
@@ -236,7 +230,7 @@ Section language.
let base := fst ret in
let b := snd ret in
(base, (a, b))
- | Unit => fun _ => (base, tt)
+ | Unit => fun v => (base, v)
| Tbase t => fun v => (S base, (base, v))
end v.
Arguments natize_interp_flat_type {var t} _ _.
@@ -263,18 +257,20 @@ Section language.
| TT => TT
| Var _ x => Var (snd x)
| Op _ _ op args => Op op (@unnatize_exprf _ _ base args)
- | LetIn _ ex _ eC => LetIn (@unnatize_exprf _ _ base ex)
- (fun x => let v := natize_interp_flat_type base x in
- @unnatize_exprf _ _ (fst v) (eC (snd v)))
- | Pair _ x _ y => Pair (@unnatize_exprf _ _ base x) (@unnatize_exprf _ _ base y)
+ | LetIn _ ex _ eC
+ => LetIn (@unnatize_exprf _ _ base ex)
+ (fun x => let v := natize_interp_flat_type base x in
+ @unnatize_exprf _ _ (fst v) (eC (snd v)))
+ | Pair _ x _ y
+ => Pair (@unnatize_exprf _ _ base x) (@unnatize_exprf _ _ base y)
end.
- Fixpoint unnatize_expr {var t} (base : nat)
- (e : @Syntax.expr base_type_code op (fun t => nat * var t)%type t)
+ Definition unnatize_expr {var t} (base : nat)
+ (e : @Syntax.expr base_type_code op (fun t => nat * var t)%type t)
: @Syntax.expr base_type_code op var t
:= match e in @Syntax.expr _ _ _ t return Syntax.expr _ _ t with
- | Return _ x => unnatize_exprf base x
- | Abs tx tR f => Abs (fun x : var tx => let v := natize_interp_flat_type (t:=Tbase tx) base x in
- @unnatize_expr _ _ (fst v) (f (snd v)))
+ | Abs tx tR f => Abs (fun x : interp_flat_type var tx =>
+ let v := natize_interp_flat_type (t:=tx) base x in
+ @unnatize_exprf _ _ (fst v) (f (snd v)))
end.
Fixpoint reflect_wffT (G : list (sigT (fun t => var1 (fst t) * var2 (snd t))%type))
@@ -312,31 +308,26 @@ Section language.
| Pair _ _ _ _, _ => rFalse
end%reified_prop.
- Fixpoint reflect_wfT (G : list (sigT (fun t => var1 (fst t) * var2 (snd t))%type))
+ Definition reflect_wfT (G : list (sigT (fun t => var1 (fst t) * var2 (snd t))%type))
{t1 t2 : type}
(e1 : @expr (fun t => nat * var1 t)%type t1)
(e2 : @expr (fun t => nat * var2 t)%type t2)
- {struct e1}
: reified_Prop
:= match e1, e2 with
- | Return _ x, Return _ y
- => reflect_wffT G x y
- | Return _ _, _ => rFalse
| Abs tx tR f, Abs tx' tR' f'
- => match @flatten_binding_list2 (Tbase tx) (Tbase tx'), type_eq_semidec_transparent tR tR' with
+ => match @flatten_binding_list2 tx tx', flat_type_eq_semidec_transparent tR tR' with
| Some G0, Some _
- => ∀ (x : interp_flat_type var1 (Tbase tx)) (x' : interp_flat_type var2 (Tbase tx')),
- @reflect_wfT (G0 x x' ++ G)%list _ _
- (f (snd (natize_interp_flat_type (List.length G) x)))
- (f' (snd (natize_interp_flat_type (List.length G) x')))
+ => ∀ (x : interp_flat_type var1 tx) (x' : interp_flat_type var2 tx'),
+ @reflect_wffT (G0 x x' ++ G)%list _ _
+ (f (snd (natize_interp_flat_type (List.length G) x)))
+ (f' (snd (natize_interp_flat_type (List.length G) x')))
| _, _ => rFalse
end
- | Abs _ _ _, _ => rFalse
end%reified_prop.
End language.
-Global Arguments reflect_wffT {_} _ {op} _ {var1 var2} G {t1 t2} _ _.
-Global Arguments reflect_wfT {_} _ {op} _ {var1 var2} G {t1 t2} _ _.
+Global Arguments reflect_wffT {_} _ {op} op_beq {var1 var2} G {t1 t2} _ _.
+Global Arguments reflect_wfT {_} _ {op} op_beq {var1 var2} G {t1 t2} _ _.
Global Arguments unnatize_exprf {_ _ _ _} _ _.
Global Arguments unnatize_expr {_ _ _ _} _ _.
Global Arguments natize_interp_flat_type {_ _ t} _ _.
diff --git a/src/Reflection/Z/BoundsInterpretations.v b/src/Reflection/Z/BoundsInterpretations.v
index 8da4ef39f..722ee40ec 100644
--- a/src/Reflection/Z/BoundsInterpretations.v
+++ b/src/Reflection/Z/BoundsInterpretations.v
@@ -123,17 +123,18 @@ Module Import Bounds.
Definition interp_op {src dst} (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst
:= match f in op src dst return interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst with
- | OpConst v => fun _ => SmartBuildBounds None v v
- | Add => fun xy => add (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Sub => fun xy => sub (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Mul => fun xy => mul (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Shl => fun xy => shl (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Shr => fun xy => shr (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Land => fun xy => land (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Lor => fun xy => lor (bit_width_of_base_type TZ) (fst xy) (snd xy)
- | Neg int_width => fun x => neg (bit_width_of_base_type TZ) int_width x
- | Cmovne => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne (bit_width_of_base_type TZ) x y z w
- | Cmovle => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle (bit_width_of_base_type TZ) x y z w
+ | OpConst TZ v => fun _ => SmartBuildBounds None v v
+ | Add T => fun xy => add (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Sub T => fun xy => sub (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Mul T => fun xy => mul (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Shl T => fun xy => shl (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Shr T => fun xy => shr (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Land T => fun xy => land (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Lor T => fun xy => lor (bit_width_of_base_type T) (fst xy) (snd xy)
+ | Neg T int_width => fun x => neg (bit_width_of_base_type T) int_width x
+ | Cmovne T => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne (bit_width_of_base_type T) x y z w
+ | Cmovle T => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle (bit_width_of_base_type T) x y z w
+ | Cast _ T => fun x => SmartRebuildBounds (bit_width_of_base_type T) x
end%bounds.
Ltac inversion_bounds :=
@@ -163,12 +164,10 @@ Module Import Bounds.
| Some b' => bounds_to_base_type' b'
end.
- (*
Definition ComputeBounds {t} (e : Expr base_type op t)
(input_bounds : interp_flat_type interp_base_type (domain t))
: interp_flat_type interp_base_type (codomain t)
:= Interp (@interp_op) e input_bounds.
- *)
Definition bound_is_goodb : forall t, interp_base_type t -> bool
:= fun t bs
diff --git a/src/Reflection/Z/CNotations.v b/src/Reflection/Z/CNotations.v
index 764094c99..bfd173094 100644
--- a/src/Reflection/Z/CNotations.v
+++ b/src/Reflection/Z/CNotations.v
@@ -44,18 +44,18 @@ Notation "'(uint32_t)' x" := (Op (Cast _ (TWord 5)) (Var x)).
Notation "'(uint64_t)' x" := (Op (Cast _ (TWord 6)) (Var x)).
Notation "'(uint128_t)' x" := (Op (Cast _ (TWord 7)) (Var x)).
*)
-Notation "x + y" := (Op (Add) (Pair x y)).
-Notation "x + y" := (Op (Add) (Pair (Var x) y)).
-Notation "x + y" := (Op (Add) (Pair x (Var y))).
-Notation "x + y" := (Op (Add) (Pair (Var x) (Var y))).
-Notation "x - y" := (Op (Sub) (Pair x y)).
-Notation "x - y" := (Op (Sub) (Pair (Var x) y)).
-Notation "x - y" := (Op (Sub) (Pair x (Var y))).
-Notation "x - y" := (Op (Sub) (Pair (Var x) (Var y))).
-Notation "x * y" := (Op (Mul) (Pair x y)).
-Notation "x * y" := (Op (Mul) (Pair (Var x) y)).
-Notation "x * y" := (Op (Mul) (Pair x (Var y))).
-Notation "x * y" := (Op (Mul) (Pair (Var x) (Var y))).
+Notation "x + y" := (Op (Add _) (Pair x y)).
+Notation "x + y" := (Op (Add _) (Pair (Var x) y)).
+Notation "x + y" := (Op (Add _) (Pair x (Var y))).
+Notation "x + y" := (Op (Add _) (Pair (Var x) (Var y))).
+Notation "x - y" := (Op (Sub _) (Pair x y)).
+Notation "x - y" := (Op (Sub _) (Pair (Var x) y)).
+Notation "x - y" := (Op (Sub _) (Pair x (Var y))).
+Notation "x - y" := (Op (Sub _) (Pair (Var x) (Var y))).
+Notation "x * y" := (Op (Mul _) (Pair x y)).
+Notation "x * y" := (Op (Mul _) (Pair (Var x) y)).
+Notation "x * y" := (Op (Mul _) (Pair x (Var y))).
+Notation "x * y" := (Op (Mul _) (Pair (Var x) (Var y))).
(* python:
<<
for opn, op in (('*', 'Mul'), ('+', 'Add'), ('&', 'Land')):
@@ -119,20 +119,18 @@ Notation "x + y" := (Op (Add (TWord 7)) (Pair x (Op (Cast _ (TWord 7)) (Var y)))
Notation "x + y" := (Op (Add (TWord 7)) (Pair (Var x) (Op (Cast _ (TWord 7)) y))).
Notation "x + y" := (Op (Add (TWord 7)) (Pair (Var x) (Op (Cast _ (TWord 7)) (Var y)))).
*)
-Notation "x >> y" := (Op (Shr) (Pair x y)).
-Notation "x >> y" := (Op (Shr) (Pair (Var x) y)).
-Notation "x >> y" := (Op (Shr) (Pair x (Var y))).
-Notation "x >> y" := (Op (Shr) (Pair (Var x) (Var y))).
-(*
+Notation "x >> y" := (Op (Shr _) (Pair x y)).
+Notation "x >> y" := (Op (Shr _) (Pair (Var x) y)).
+Notation "x >> y" := (Op (Shr _) (Pair x (Var y))).
+Notation "x >> y" := (Op (Shr _) (Pair (Var x) (Var y))).
Notation "x >> y" := (Op (Shr _) (Pair x (Op (Cast _ _) y))).
Notation "x >> y" := (Op (Shr _) (Pair (Var x) (Op (Cast _ _) y))).
Notation "x >> y" := (Op (Shr _) (Pair x (Op (Cast _ _) (Var y)))).
Notation "x >> y" := (Op (Shr _) (Pair (Var x) (Op (Cast _ _) (Var y)))).
-*)
-Notation "x & y" := (Op (Land) (Pair x y)).
-Notation "x & y" := (Op (Land) (Pair (Var x) y)).
-Notation "x & y" := (Op (Land) (Pair x (Var y))).
-Notation "x & y" := (Op (Land) (Pair (Var x) (Var y))).
+Notation "x & y" := (Op (Land _) (Pair x y)).
+Notation "x & y" := (Op (Land _) (Pair (Var x) y)).
+Notation "x & y" := (Op (Land _) (Pair x (Var y))).
+Notation "x & y" := (Op (Land _) (Pair (Var x) (Var y))).
(*
Notation "x & y" := (Op (Land (TWord 5)) (Pair (Op (Cast _ (TWord 5)) x) y)).
Notation "x & y" := (Op (Land (TWord 5)) (Pair (Op (Cast _ (TWord 5)) x) (Var y))).
diff --git a/src/Reflection/Z/Interpretations128/Relations.v b/src/Reflection/Z/Interpretations128/Relations.v
index 7f6f67fa2..8ea7de125 100644
--- a/src/Reflection/Z/Interpretations128/Relations.v
+++ b/src/Reflection/Z/Interpretations128/Relations.v
@@ -340,11 +340,12 @@ Local Ltac unfold_related_const :=
Lemma related_wordW_op : related_op related_wordW (@BoundedWordW.interp_op) (@WordW.interp_op).
Proof.
- (let op := fresh in intros ?? op; destruct op; simpl);
+ (let op := fresh in intros ?? op; destruct op; simpl); destruct_head' base_type;
try first [ apply related_wordW_t_map1
| apply related_wordW_t_map2
| apply related_wordW_t_map4
- | unfold_related_const; break_innermost_match; reflexivity ].
+ | unfold_related_const; break_innermost_match; reflexivity
+ | exact (fun _ _ x => x) ].
Qed.
Lemma related_bounds_t_map1 opW opB pf
@@ -411,7 +412,7 @@ Local Ltac related_const_op_t :=
Lemma related_bounds_op : related_op related_bounds (@BoundedWordW.interp_op) (@ZBounds.interp_op).
Proof.
- let op := fresh in intros ?? op; destruct op; simpl.
+ let op := fresh in intros ?? op; destruct op; simpl; destruct_head' base_type.
{ related_const_op_t. }
{ apply related_bounds_t_map2; intros; destruct_head' option; reflexivity. }
{ apply related_bounds_t_map2; intros; destruct_head' option; reflexivity. }
@@ -423,6 +424,7 @@ Proof.
{ apply related_bounds_t_map1; intros; destruct_head' option; unfold ZBounds.neg; break_match; reflexivity. }
{ apply related_bounds_t_map4; intros; destruct_head' option; reflexivity. }
{ apply related_bounds_t_map4; intros; destruct_head' option; reflexivity. }
+ { exact (fun _ _ x => x). }
Qed.
Local Ltac WordW.Rewrites.wordW_util_arith ::=
@@ -541,7 +543,7 @@ Local Arguments ZBounds.neg _ !_ / .
Lemma related_Z_op : related_op related_Z (@BoundedWordW.interp_op) (@Z.interp_op).
Proof.
- let op := fresh in intros ?? op; destruct op; simpl.
+ let op := fresh in intros ?? op; destruct op; simpl; destruct_head' base_type.
{ related_const_op_t. }
{ apply related_Z_t_map2; related_Z_op_fin_t. }
{ apply related_Z_t_map2; related_Z_op_fin_t. }
@@ -553,6 +555,7 @@ Proof.
{ apply related_Z_t_map1; related_Z_op_fin_t. }
{ apply related_Z_t_map4; related_Z_op_fin_t. }
{ apply related_Z_t_map4; related_Z_op_fin_t. }
+ { exact (fun _ _ x => x). }
Qed.
Create HintDb interp_related discriminated.
diff --git a/src/Reflection/Z/Interpretations128/RelationsCombinations.v b/src/Reflection/Z/Interpretations128/RelationsCombinations.v
index 68fca675e..6e7eb2865 100644
--- a/src/Reflection/Z/Interpretations128/RelationsCombinations.v
+++ b/src/Reflection/Z/Interpretations128/RelationsCombinations.v
@@ -1,9 +1,9 @@
Require Import Coq.ZArith.ZArith.
+Require Import Coq.Classes.RelationClasses.
Require Import Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Z.InterpretationsGen.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Z.Interpretations128.Relations.
@@ -14,36 +14,6 @@ Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Tactics.
Module Relations.
- Section lift.
- Context {interp_base_type1 interp_base_type2 : base_type -> Type}
- (R : forall t, interp_base_type1 t -> interp_base_type2 t -> Prop).
-
- Definition interp_type_rel_pointwise2_uncurried
- {t : type base_type}
- := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> _ with
- | Tflat T => fun f g => interp_flat_type_rel_pointwise (t:=T) R f g
- | Arrow A B
- => fun f g
- => forall x y, interp_flat_type_rel_pointwise R x y
- -> interp_flat_type_rel_pointwise R (ApplyInterpedAll f x) (ApplyInterpedAll g y)
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2
- {t f g}
- : interp_type_rel_pointwise2 (t:=t) R f g
- <-> interp_type_rel_pointwise2_uncurried (t:=t) f g.
- Proof.
- unfold interp_type_rel_pointwise2_uncurried.
- induction t as [|A B IHt]; [ reflexivity | ].
- { simpl; unfold Morphisms.respectful_hetero in *; destruct B.
- { reflexivity. }
- { setoid_rewrite IHt; clear IHt.
- split; intro H; intros.
- { destruct_head_hnf' prod; simpl in *; intuition. }
- { eapply (H (_, _) (_, _)); simpl in *; intuition. } } }
- Qed.
- End lift.
-
Section proj.
Context {interp_base_type1 interp_base_type2}
(proj : forall t : base_type, interp_base_type1 t -> interp_base_type2 t).
@@ -51,43 +21,27 @@ Module Relations.
Let R {t : flat_type base_type} f g :=
SmartVarfMap (t:=t) proj f = g.
- Definition interp_type_rel_pointwise2_uncurried_proj
+ Definition interp_type_rel_pointwise_uncurried_proj
{t : type base_type}
: interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type interp_base_type1 (all_binders_for (Arrow A B)),
- let y := SmartVarfMap proj x in
- let fx := ApplyInterpedAll f x in
- let gy := ApplyInterpedAll g y in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj
+ := fun f g
+ => forall x : interp_flat_type interp_base_type1 (domain t),
+ let y := SmartVarfMap proj x in
+ let fx := f x in
+ let gy := g y in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj
{t : type base_type}
- {f : interp_type interp_base_type1 t}
+ {f}
{g}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj (t:=t) f g.
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress subst
- | reflexivity ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt;
- repeat first [ reflexivity
- | progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ eauto.
Qed.
End proj.
@@ -102,49 +56,28 @@ Module Relations.
| None => True
end.
- Definition interp_type_rel_pointwise2_uncurried_proj_option
+ Definition interp_type_rel_pointwise_uncurried_proj_option
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
- let y := SmartVarfMap proj_option x in
- let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
- let gy := ApplyInterpedAll g y in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_option
+ := fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (domain t),
+ let y := SmartVarfMap proj_option x in
+ let fx := f (LiftOption.to' (Some x)) in
+ let gy := g y in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_option
{t : type base_type}
- {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
+ {f}
{g}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj_option (t:=t) f g.
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj_option (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_option.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt.
- { repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match
- | reflexivity ]. }
- { simpl in *; break_match; reflexivity. } }
+ unfold interp_type_rel_pointwise_uncurried_proj_option.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ intros H x; apply H; simpl.
+ rewrite LiftOption.of'_to'; reflexivity.
Qed.
End proj_option.
@@ -162,52 +95,58 @@ Module Relations.
| None, _ => False
end.
- Definition interp_type_rel_pointwise2_uncurried_proj_option2
+ Definition interp_type_rel_pointwise_uncurried_proj_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop
- := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
- let y := SmartVarfMap (fun _ => proj) x in
- let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
- let gy := ApplyInterpedAll g (LiftOption.to' (Some y)) in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_option2
+ := fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (domain t),
+ let y := SmartVarfMap (fun _ => proj) x in
+ let fx := f (LiftOption.to' (Some x)) in
+ let gy := g (LiftOption.to' (Some y)) in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_option2
{t : type base_type}
- {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
- {g : interp_type (LiftOption.interp_base_type' interp_base_type2) t}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj_option2 (t:=t) f g.
+ {f}
+ {g}
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj_option2 (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt.
- { repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match
- | reflexivity ]. }
- { simpl in *; break_match; reflexivity. } }
+ unfold interp_type_rel_pointwise_uncurried_proj_option2.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ intros H x; apply H; simpl.
+ rewrite !LiftOption.of'_to'; reflexivity.
Qed.
End proj_option2.
+ Local Ltac t proj012 :=
+ repeat match goal with
+ | _ => progress cbv beta in *
+ | _ => progress break_match; try tauto; []
+ | _ => progress subst
+ | [ H : _ |- _ ]
+ => first [ rewrite !LiftOption.lift_relation_flat_type_pointwise in H
+ by (eassumption || rewrite LiftOption.of'_to'; reflexivity)
+ | rewrite !LiftOption.lift_relation2_flat_type_pointwise in H
+ by (eassumption || rewrite LiftOption.of'_to'; reflexivity)
+ | rewrite !@lift_interp_flat_type_rel_pointwise_f_eq_id2 in H
+ | rewrite !@lift_interp_flat_type_rel_pointwise_f_eq in H ]
+ | _ => progress unfold proj_eq_rel in *
+ | _ => progress specialize_by reflexivity
+ | _ => rewrite SmartVarfMap_compose
+ | _ => setoid_rewrite proj012
+ | [ |- context G[fun x y => ?f x y] ]
+ => let G' := context G[f] in change G'
+ | [ |- context G[fun (_ : ?T) x => ?f x] ]
+ => let G' := context G[fun _ : T => f] in change G'
+ | [ H : context G[fun (_ : ?T) x => ?f x] |- _ ]
+ => let G' := context G[fun _ : T => f] in change G' in H
+ | _ => rewrite_hyp <- !*; []
+ | _ => reflexivity
+ | _ => rewrite interp_flat_type_rel_pointwise_SmartVarfMap
+ end.
+
Section proj_from_option2.
Context {interp_base_type0 : Type} {interp_base_type1 interp_base_type2 : base_type -> Type}
(proj01 : forall t, interp_base_type0 -> interp_base_type1 t)
@@ -217,64 +156,41 @@ Module Relations.
Let R {t : flat_type base_type} f g :=
proj_eq_rel (SmartVarfMap proj (t:=t)) f g.
- Definition interp_type_rel_pointwise2_uncurried_proj_from_option2
+ Definition interp_type_rel_pointwise_uncurried_proj_from_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
- | Tflat T => fun f0 f g => match LiftOption.of' f0 with
- | Some _ => True
- | None => False
- end -> @R _ f g
- | Arrow A B
- => fun f0 f g
- => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
- let x' := SmartVarfMap proj01 x in
- let y' := SmartVarfMap proj x' in
- let fx := ApplyInterpedAll f x' in
- let gy := ApplyInterpedAll g y' in
- let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
- match f0x with
- | Some _ => True
- | None => False
- end
- -> @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_from_option2
+ := fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (domain t),
+ let x' := SmartVarfMap proj01 x in
+ let y' := SmartVarfMap proj x' in
+ let fx := f x' in
+ let gy := g y' in
+ let f0x := LiftOption.of' (f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_from_option2
{t : type base_type}
{f0}
{f : interp_type interp_base_type1 t}
{g : interp_type interp_base_type2 t}
(proj012 : forall t x, proj t (proj01 t x) = proj02 t x)
- : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj01 t))) f0 f
- -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
- -> interp_type_rel_pointwise2_uncurried_proj_from_option2 (t:=t) f0 f g.
+ : interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj01 t))) f0 f
+ -> interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise_uncurried_proj_from_option2 (t:=t) f0 f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_from_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit; try reflexivity.
- { cbv [LiftOption.lift_relation proj_eq_rel R].
- break_match; try tauto; intros; subst.
- apply proj012. }
- { intros [HA HB] [HA' HB'] Hrel.
- specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
- unfold R, proj_eq_rel in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. } }
- { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
- repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
- | break_match; rewrite <- ?proj012; reflexivity ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj_from_option2, Morphisms.respectful_hetero.
+ intros H0 H1 x.
+ specialize (H0 (LiftOption.to' (Some x)) (SmartVarfMap proj01 x)).
+ specialize (H1 (LiftOption.to' (Some x)) (SmartVarfMap proj02 x)).
+ subst R.
+ t proj012.
Qed.
End proj_from_option2.
- Global Arguments uncurry_interp_type_rel_pointwise2_proj_from_option2 {_ _ _ _ _} proj {t f0 f g} _ _ _.
+ Global Arguments uncurry_interp_type_rel_pointwise_proj_from_option2 {_ _ _ _ _} proj {t f0 f g} _ _ _.
Section proj1_from_option2.
Context {interp_base_type0 interp_base_type1 : Type} {interp_base_type2 : base_type -> Type}
@@ -282,70 +198,43 @@ Module Relations.
(proj02 : forall t, interp_base_type0 -> interp_base_type2 t)
(R : forall t, interp_base_type1 -> interp_base_type2 t -> Prop).
- Definition interp_type_rel_pointwise2_uncurried_proj1_from_option2
+ Definition interp_type_rel_pointwise_uncurried_proj1_from_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
- | Tflat T => fun f0 f g => match LiftOption.of' f0 with
- | Some _ => True
- | None => False
- end -> match LiftOption.of' f with
- | Some f' => interp_flat_type_rel_pointwise (@R) f' g
- | None => True
- end
- | Arrow A B
- => fun f0 f g
- => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
- let x' := SmartVarfMap (fun _ => proj01) x in
- let y' := SmartVarfMap proj02 x in
- let fx := LiftOption.of' (ApplyInterpedAll f (LiftOption.to' (Some x'))) in
- let gy := ApplyInterpedAll g y' in
- let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
- match f0x with
- | Some _ => True
- | None => False
- end
- -> match fx with
- | Some fx' => interp_flat_type_rel_pointwise (@R) fx' gy
- | None => True
- end
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj1_from_option2
+ := fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (domain t),
+ let x' := SmartVarfMap (fun _ => proj01) x in
+ let y' := SmartVarfMap proj02 x in
+ let fx := LiftOption.of' (f (LiftOption.to' (Some x'))) in
+ let gy := g y' in
+ let f0x := LiftOption.of' (f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> match fx with
+ | Some fx' => interp_flat_type_rel_pointwise (@R) fx' gy
+ | None => True
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj1_from_option2
{t : type base_type}
{f0}
{f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
{g : interp_type interp_base_type2 t}
- (proj012R : forall t x, @R _ (proj01 x) (proj02 t x))
- : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation2 (proj_eq_rel proj01)) f0 f
- -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
- -> interp_type_rel_pointwise2_uncurried_proj1_from_option2 (t:=t) f0 f g.
+ (proj012R : forall t, Reflexive (fun x y => @R _ (proj01 x) (proj02 t y)))
+ : interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation2 (proj_eq_rel proj01)) f0 f
+ -> interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise_uncurried_proj1_from_option2 (t:=t) f0 f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj1_from_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit; try reflexivity.
- { cbv [LiftOption.lift_relation proj_eq_rel LiftOption.lift_relation2].
- break_match; try tauto; intros; subst.
- apply proj012R. }
- { intros [HA HB] [HA' HB'] Hrel.
- specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
- unfold proj_eq_rel in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. } }
- { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
- repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
- | break_match; reflexivity ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj1_from_option2, Morphisms.respectful_hetero.
+ intros H0 H1 x.
+ specialize (H0 (LiftOption.to' (Some x)) (LiftOption.to' (Some (SmartVarfMap (fun _ => proj01) x)))).
+ specialize (H1 (LiftOption.to' (Some x)) (SmartVarfMap proj02 x)).
+ t proj012.
Qed.
End proj1_from_option2.
- Global Arguments uncurry_interp_type_rel_pointwise2_proj1_from_option2 {_ _ _ _ _} R {t f0 f g} _ _ _.
+ Global Arguments uncurry_interp_type_rel_pointwise_proj1_from_option2 {_ _ _ _ _} R {t f0 f g} _ _ _.
Section combine_related.
Lemma related_flat_transitivity {interp_base_type1 interp_base_type2 interp_base_type3}
diff --git a/src/Reflection/Z/Interpretations64/Relations.v b/src/Reflection/Z/Interpretations64/Relations.v
index 02934c46a..3491c9be5 100644
--- a/src/Reflection/Z/Interpretations64/Relations.v
+++ b/src/Reflection/Z/Interpretations64/Relations.v
@@ -341,10 +341,12 @@ Local Ltac unfold_related_const :=
Lemma related_wordW_op : related_op related_wordW (@BoundedWordW.interp_op) (@WordW.interp_op).
Proof.
(let op := fresh in intros ?? op; destruct op; simpl);
+ destruct_head' base_type;
try first [ apply related_wordW_t_map1
| apply related_wordW_t_map2
| apply related_wordW_t_map4
- | unfold_related_const; break_innermost_match; reflexivity ].
+ | unfold_related_const; break_innermost_match; reflexivity
+ | exact (fun _ _ x => x) ].
Qed.
Lemma related_bounds_t_map1 opW opB pf
@@ -411,7 +413,7 @@ Local Ltac related_const_op_t :=
Lemma related_bounds_op : related_op related_bounds (@BoundedWordW.interp_op) (@ZBounds.interp_op).
Proof.
- let op := fresh in intros ?? op; destruct op; simpl.
+ let op := fresh in intros ?? op; destruct op; simpl; destruct_head' base_type.
{ related_const_op_t. }
{ apply related_bounds_t_map2; intros; destruct_head' option; reflexivity. }
{ apply related_bounds_t_map2; intros; destruct_head' option; reflexivity. }
@@ -423,6 +425,7 @@ Proof.
{ apply related_bounds_t_map1; intros; destruct_head' option; unfold ZBounds.neg; break_match; reflexivity. }
{ apply related_bounds_t_map4; intros; destruct_head' option; reflexivity. }
{ apply related_bounds_t_map4; intros; destruct_head' option; reflexivity. }
+ { exact (fun _ _ x => x). }
Qed.
Local Ltac WordW.Rewrites.wordW_util_arith ::=
@@ -541,7 +544,7 @@ Local Arguments ZBounds.neg _ !_ / .
Lemma related_Z_op : related_op related_Z (@BoundedWordW.interp_op) (@Z.interp_op).
Proof.
- let op := fresh in intros ?? op; destruct op; simpl.
+ let op := fresh in intros ?? op; destruct op; simpl; destruct_head' base_type.
{ related_const_op_t. }
{ apply related_Z_t_map2; related_Z_op_fin_t. }
{ apply related_Z_t_map2; related_Z_op_fin_t. }
@@ -553,6 +556,7 @@ Proof.
{ apply related_Z_t_map1; related_Z_op_fin_t. }
{ apply related_Z_t_map4; related_Z_op_fin_t. }
{ apply related_Z_t_map4; related_Z_op_fin_t. }
+ { exact (fun _ _ x => x). }
Qed.
Create HintDb interp_related discriminated.
diff --git a/src/Reflection/Z/Interpretations64/RelationsCombinations.v b/src/Reflection/Z/Interpretations64/RelationsCombinations.v
index 3a95bcc51..2e05b18de 100644
--- a/src/Reflection/Z/Interpretations64/RelationsCombinations.v
+++ b/src/Reflection/Z/Interpretations64/RelationsCombinations.v
@@ -1,9 +1,9 @@
Require Import Coq.ZArith.ZArith.
+Require Import Coq.Classes.RelationClasses.
Require Import Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Z.InterpretationsGen.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Z.Interpretations64.Relations.
@@ -14,36 +14,6 @@ Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Tactics.
Module Relations.
- Section lift.
- Context {interp_base_type1 interp_base_type2 : base_type -> Type}
- (R : forall t, interp_base_type1 t -> interp_base_type2 t -> Prop).
-
- Definition interp_type_rel_pointwise2_uncurried
- {t : type base_type}
- := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> _ with
- | Tflat T => fun f g => interp_flat_type_rel_pointwise (t:=T) R f g
- | Arrow A B
- => fun f g
- => forall x y, interp_flat_type_rel_pointwise R x y
- -> interp_flat_type_rel_pointwise R (ApplyInterpedAll f x) (ApplyInterpedAll g y)
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2
- {t f g}
- : interp_type_rel_pointwise2 (t:=t) R f g
- <-> interp_type_rel_pointwise2_uncurried (t:=t) f g.
- Proof.
- unfold interp_type_rel_pointwise2_uncurried.
- induction t as [|A B IHt]; [ reflexivity | ].
- { simpl; unfold Morphisms.respectful_hetero in *; destruct B.
- { reflexivity. }
- { setoid_rewrite IHt; clear IHt.
- split; intro H; intros.
- { destruct_head_hnf' prod; simpl in *; intuition. }
- { eapply (H (_, _) (_, _)); simpl in *; intuition. } } }
- Qed.
- End lift.
-
Section proj.
Context {interp_base_type1 interp_base_type2}
(proj : forall t : base_type, interp_base_type1 t -> interp_base_type2 t).
@@ -51,43 +21,27 @@ Module Relations.
Let R {t : flat_type base_type} f g :=
SmartVarfMap (t:=t) proj f = g.
- Definition interp_type_rel_pointwise2_uncurried_proj
+ Definition interp_type_rel_pointwise_uncurried_proj
{t : type base_type}
: interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type interp_base_type1 (all_binders_for (Arrow A B)),
- let y := SmartVarfMap proj x in
- let fx := ApplyInterpedAll f x in
- let gy := ApplyInterpedAll g y in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj
+ := fun f g
+ => forall x : interp_flat_type interp_base_type1 (domain t),
+ let y := SmartVarfMap proj x in
+ let fx := f x in
+ let gy := g y in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj
{t : type base_type}
- {f : interp_type interp_base_type1 t}
+ {f}
{g}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj (t:=t) f g.
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress subst
- | reflexivity ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt;
- repeat first [ reflexivity
- | progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ eauto.
Qed.
End proj.
@@ -102,49 +56,28 @@ Module Relations.
| None => True
end.
- Definition interp_type_rel_pointwise2_uncurried_proj_option
+ Definition interp_type_rel_pointwise_uncurried_proj_option
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
- let y := SmartVarfMap proj_option x in
- let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
- let gy := ApplyInterpedAll g y in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_option
+ := fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (domain t),
+ let y := SmartVarfMap proj_option x in
+ let fx := f (LiftOption.to' (Some x)) in
+ let gy := g y in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_option
{t : type base_type}
- {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
+ {f}
{g}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj_option (t:=t) f g.
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj_option (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_option.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt.
- { repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match
- | reflexivity ]. }
- { simpl in *; break_match; reflexivity. } }
+ unfold interp_type_rel_pointwise_uncurried_proj_option.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ intros H x; apply H; simpl.
+ rewrite LiftOption.of'_to'; reflexivity.
Qed.
End proj_option.
@@ -162,52 +95,58 @@ Module Relations.
| None, _ => False
end.
- Definition interp_type_rel_pointwise2_uncurried_proj_option2
+ Definition interp_type_rel_pointwise_uncurried_proj_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop
- := match t return interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type (LiftOption.interp_base_type' interp_base_type2) t -> Prop with
- | Tflat T => @R _
- | Arrow A B
- => fun f g
- => forall x : interp_flat_type (fun _ => interp_base_type1) (all_binders_for (Arrow A B)),
- let y := SmartVarfMap (fun _ => proj) x in
- let fx := ApplyInterpedAll f (LiftOption.to' (Some x)) in
- let gy := ApplyInterpedAll g (LiftOption.to' (Some y)) in
- @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_option2
+ := fun f g
+ => forall x : interp_flat_type (fun _ => interp_base_type1) (domain t),
+ let y := SmartVarfMap (fun _ => proj) x in
+ let fx := f (LiftOption.to' (Some x)) in
+ let gy := g (LiftOption.to' (Some y)) in
+ @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_option2
{t : type base_type}
- {f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
- {g : interp_type (LiftOption.interp_base_type' interp_base_type2) t}
- : interp_type_rel_pointwise2 (t:=t) (fun t => @R _) f g
- -> interp_type_rel_pointwise2_uncurried_proj_option2 (t:=t) f g.
+ {f}
+ {g}
+ : (forall x y, @R (domain t) x y -> @R (codomain t) (f x) (g y))
+ -> interp_type_rel_pointwise_uncurried_proj_option2 (t:=t) f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit;
- [ solve [ trivial | reflexivity ] | reflexivity | ].
- intros [HA HB].
- specialize (IHA _ _ HA); specialize (IHB _ _ HB).
- unfold R in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. }
- { destruct B; intros H ?; apply IHt, H; clear IHt.
- { repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of' in *
- | progress break_match
- | reflexivity ]. }
- { simpl in *; break_match; reflexivity. } }
+ unfold interp_type_rel_pointwise_uncurried_proj_option2.
+ destruct t as [A B]; simpl in *.
+ subst R; simpl in *.
+ intros H x; apply H; simpl.
+ rewrite !LiftOption.of'_to'; reflexivity.
Qed.
End proj_option2.
+ Local Ltac t proj012 :=
+ repeat match goal with
+ | _ => progress cbv beta in *
+ | _ => progress break_match; try tauto; []
+ | _ => progress subst
+ | [ H : _ |- _ ]
+ => first [ rewrite !LiftOption.lift_relation_flat_type_pointwise in H
+ by (eassumption || rewrite LiftOption.of'_to'; reflexivity)
+ | rewrite !LiftOption.lift_relation2_flat_type_pointwise in H
+ by (eassumption || rewrite LiftOption.of'_to'; reflexivity)
+ | rewrite !@lift_interp_flat_type_rel_pointwise_f_eq_id2 in H
+ | rewrite !@lift_interp_flat_type_rel_pointwise_f_eq in H ]
+ | _ => progress unfold proj_eq_rel in *
+ | _ => progress specialize_by reflexivity
+ | _ => rewrite SmartVarfMap_compose
+ | _ => setoid_rewrite proj012
+ | [ |- context G[fun x y => ?f x y] ]
+ => let G' := context G[f] in change G'
+ | [ |- context G[fun (_ : ?T) x => ?f x] ]
+ => let G' := context G[fun _ : T => f] in change G'
+ | [ H : context G[fun (_ : ?T) x => ?f x] |- _ ]
+ => let G' := context G[fun _ : T => f] in change G' in H
+ | _ => rewrite_hyp <- !*; []
+ | _ => reflexivity
+ | _ => rewrite interp_flat_type_rel_pointwise_SmartVarfMap
+ end.
+
Section proj_from_option2.
Context {interp_base_type0 : Type} {interp_base_type1 interp_base_type2 : base_type -> Type}
(proj01 : forall t, interp_base_type0 -> interp_base_type1 t)
@@ -217,64 +156,41 @@ Module Relations.
Let R {t : flat_type base_type} f g :=
proj_eq_rel (SmartVarfMap proj (t:=t)) f g.
- Definition interp_type_rel_pointwise2_uncurried_proj_from_option2
+ Definition interp_type_rel_pointwise_uncurried_proj_from_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type interp_base_type1 t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
- | Tflat T => fun f0 f g => match LiftOption.of' f0 with
- | Some _ => True
- | None => False
- end -> @R _ f g
- | Arrow A B
- => fun f0 f g
- => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
- let x' := SmartVarfMap proj01 x in
- let y' := SmartVarfMap proj x' in
- let fx := ApplyInterpedAll f x' in
- let gy := ApplyInterpedAll g y' in
- let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
- match f0x with
- | Some _ => True
- | None => False
- end
- -> @R _ fx gy
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj_from_option2
+ := fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (domain t),
+ let x' := SmartVarfMap proj01 x in
+ let y' := SmartVarfMap proj x' in
+ let fx := f x' in
+ let gy := g y' in
+ let f0x := LiftOption.of' (f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> @R _ fx gy.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj_from_option2
{t : type base_type}
{f0}
{f : interp_type interp_base_type1 t}
{g : interp_type interp_base_type2 t}
(proj012 : forall t x, proj t (proj01 t x) = proj02 t x)
- : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj01 t))) f0 f
- -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
- -> interp_type_rel_pointwise2_uncurried_proj_from_option2 (t:=t) f0 f g.
+ : interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj01 t))) f0 f
+ -> interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise_uncurried_proj_from_option2 (t:=t) f0 f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj_from_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit; try reflexivity.
- { cbv [LiftOption.lift_relation proj_eq_rel R].
- break_match; try tauto; intros; subst.
- apply proj012. }
- { intros [HA HB] [HA' HB'] Hrel.
- specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
- unfold R, proj_eq_rel in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. } }
- { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
- repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
- | break_match; rewrite <- ?proj012; reflexivity ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj_from_option2, Morphisms.respectful_hetero.
+ intros H0 H1 x.
+ specialize (H0 (LiftOption.to' (Some x)) (SmartVarfMap proj01 x)).
+ specialize (H1 (LiftOption.to' (Some x)) (SmartVarfMap proj02 x)).
+ subst R.
+ t proj012.
Qed.
End proj_from_option2.
- Global Arguments uncurry_interp_type_rel_pointwise2_proj_from_option2 {_ _ _ _ _} proj {t f0 f g} _ _ _.
+ Global Arguments uncurry_interp_type_rel_pointwise_proj_from_option2 {_ _ _ _ _} proj {t f0 f g} _ _ _.
Section proj1_from_option2.
Context {interp_base_type0 interp_base_type1 : Type} {interp_base_type2 : base_type -> Type}
@@ -282,70 +198,43 @@ Module Relations.
(proj02 : forall t, interp_base_type0 -> interp_base_type2 t)
(R : forall t, interp_base_type1 -> interp_base_type2 t -> Prop).
- Definition interp_type_rel_pointwise2_uncurried_proj1_from_option2
+ Definition interp_type_rel_pointwise_uncurried_proj1_from_option2
{t : type base_type}
: interp_type (LiftOption.interp_base_type' interp_base_type0) t -> interp_type (LiftOption.interp_base_type' interp_base_type1) t -> interp_type interp_base_type2 t -> Prop
- := match t return interp_type _ t -> interp_type _ t -> interp_type _ t -> Prop with
- | Tflat T => fun f0 f g => match LiftOption.of' f0 with
- | Some _ => True
- | None => False
- end -> match LiftOption.of' f with
- | Some f' => interp_flat_type_rel_pointwise (@R) f' g
- | None => True
- end
- | Arrow A B
- => fun f0 f g
- => forall x : interp_flat_type (fun _ => interp_base_type0) (all_binders_for (Arrow A B)),
- let x' := SmartVarfMap (fun _ => proj01) x in
- let y' := SmartVarfMap proj02 x in
- let fx := LiftOption.of' (ApplyInterpedAll f (LiftOption.to' (Some x'))) in
- let gy := ApplyInterpedAll g y' in
- let f0x := LiftOption.of' (ApplyInterpedAll f0 (LiftOption.to' (Some x))) in
- match f0x with
- | Some _ => True
- | None => False
- end
- -> match fx with
- | Some fx' => interp_flat_type_rel_pointwise (@R) fx' gy
- | None => True
- end
- end.
-
- Lemma uncurry_interp_type_rel_pointwise2_proj1_from_option2
+ := fun f0 f g
+ => forall x : interp_flat_type (fun _ => interp_base_type0) (domain t),
+ let x' := SmartVarfMap (fun _ => proj01) x in
+ let y' := SmartVarfMap proj02 x in
+ let fx := LiftOption.of' (f (LiftOption.to' (Some x'))) in
+ let gy := g y' in
+ let f0x := LiftOption.of' (f0 (LiftOption.to' (Some x))) in
+ match f0x with
+ | Some _ => True
+ | None => False
+ end
+ -> match fx with
+ | Some fx' => interp_flat_type_rel_pointwise (@R) fx' gy
+ | None => True
+ end.
+
+ Lemma uncurry_interp_type_rel_pointwise_proj1_from_option2
{t : type base_type}
{f0}
{f : interp_type (LiftOption.interp_base_type' interp_base_type1) t}
{g : interp_type interp_base_type2 t}
- (proj012R : forall t x, @R _ (proj01 x) (proj02 t x))
- : interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation2 (proj_eq_rel proj01)) f0 f
- -> interp_type_rel_pointwise2 (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
- -> interp_type_rel_pointwise2_uncurried_proj1_from_option2 (t:=t) f0 f g.
+ (proj012R : forall t, Reflexive (fun x y => @R _ (proj01 x) (proj02 t y)))
+ : interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation2 (proj_eq_rel proj01)) f0 f
+ -> interp_type_rel_pointwise (t:=t) (LiftOption.lift_relation (fun t => proj_eq_rel (proj02 t))) f0 g
+ -> interp_type_rel_pointwise_uncurried_proj1_from_option2 (t:=t) f0 f g.
Proof.
- unfold interp_type_rel_pointwise2_uncurried_proj1_from_option2.
- induction t as [t|A B IHt]; simpl; unfold Morphisms.respectful_hetero in *.
- { induction t as [t| |A IHA B IHB]; simpl; destruct_head_hnf' unit; try reflexivity.
- { cbv [LiftOption.lift_relation proj_eq_rel LiftOption.lift_relation2].
- break_match; try tauto; intros; subst.
- apply proj012R. }
- { intros [HA HB] [HA' HB'] Hrel.
- specialize (IHA _ _ _ HA HA'); specialize (IHB _ _ _ HB HB').
- unfold proj_eq_rel in *.
- repeat first [ progress destruct_head_hnf' prod
- | progress simpl in *
- | progress unfold LiftOption.of' in *
- | progress break_match
- | progress break_match_hyps
- | progress inversion_prod
- | progress inversion_option
- | reflexivity
- | progress intuition subst ]. } }
- { destruct B; intros H0 H1 ?; apply IHt; clear IHt; first [ apply H0 | apply H1 ];
- repeat first [ progress simpl in *
- | progress unfold R, LiftOption.of', proj_eq_rel, LiftOption.lift_relation in *
- | break_match; reflexivity ]. }
+ unfold interp_type_rel_pointwise_uncurried_proj1_from_option2, Morphisms.respectful_hetero.
+ intros H0 H1 x.
+ specialize (H0 (LiftOption.to' (Some x)) (LiftOption.to' (Some (SmartVarfMap (fun _ => proj01) x)))).
+ specialize (H1 (LiftOption.to' (Some x)) (SmartVarfMap proj02 x)).
+ t proj012.
Qed.
End proj1_from_option2.
- Global Arguments uncurry_interp_type_rel_pointwise2_proj1_from_option2 {_ _ _ _ _} R {t f0 f g} _ _ _.
+ Global Arguments uncurry_interp_type_rel_pointwise_proj1_from_option2 {_ _ _ _ _} R {t f0 f g} _ _ _.
Section combine_related.
Lemma related_flat_transitivity {interp_base_type1 interp_base_type2 interp_base_type3}
diff --git a/src/Reflection/Z/InterpretationsGen.v b/src/Reflection/Z/InterpretationsGen.v
index f11837e60..6fa2ff8da 100644
--- a/src/Reflection/Z/InterpretationsGen.v
+++ b/src/Reflection/Z/InterpretationsGen.v
@@ -3,7 +3,7 @@ Require Import Coq.ZArith.ZArith.
Require Import Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
+Require Import Crypto.Reflection.Relations.
Require Import Crypto.ModularArithmetic.ModularBaseSystemListZOperations.
Require Import Crypto.Util.Equality.
Require Import Crypto.Util.ZUtil.
@@ -53,9 +53,7 @@ Module InterpretationsGen (Bit : BitSize).
:= option (interp_flat_type (fun _ => T) t).
Definition interp_base_type' (t : base_type)
- := match t with
- | TZ => option T
- end.
+ := option T.
Definition of' {t} : Syntax.interp_flat_type interp_base_type' t -> interp_flat_type t
:= @smart_interp_flat_map
@@ -69,41 +67,115 @@ Module InterpretationsGen (Bit : BitSize).
end)
t.
+ Lemma of'_pair {A B} x
+ : @of' (A * B) x = match of' (fst x), of' (snd x) with
+ | Some x', Some y' => Some (x', y')
+ | _, _ => None
+ end.
+ Proof. reflexivity. Qed.
+
Fixpoint to' {t} : interp_flat_type t -> Syntax.interp_flat_type interp_base_type' t
:= match t return interp_flat_type t -> Syntax.interp_flat_type interp_base_type' t with
- | Tbase TZ => fun x => x
+ | Tbase _ => fun x => x
| Unit => fun _ => tt
| Prod A B => fun x => (@to' A (option_map (@fst _ _) x),
@to' B (option_map (@snd _ _) x))
end.
- Definition lift_relation {interp_base_type2}
- (R : forall t, T -> interp_base_type2 t -> Prop)
- : forall t, interp_base_type' t -> interp_base_type2 t -> Prop
- := fun t x y => match of' (t:=Tbase t) x with
- | Some x' => R t x' y
- | None => True
- end.
-
- Definition Some {t} (x : T) : interp_base_type' t
- := match t with
- | TZ => Some x
- end.
+ Lemma of'_to' {t} v : of' (@to' t (Some v)) = Some v.
+ Proof.
+ induction t;
+ repeat first [ progress simpl
+ | progress destruct_head_hnf prod
+ | progress destruct_head_hnf unit
+ | progress destruct_head base_type
+ | rewrite of'_pair
+ | rewrite_hyp !*
+ | reflexivity ].
+ Qed.
+
+ Section lift_relation.
+ Context {interp_base_type2 : base_type -> Type}
+ (R : forall t, T -> interp_base_type2 t -> Prop).
+ Definition lift_relation
+ : forall t, interp_base_type' t -> interp_base_type2 t -> Prop
+ := fun t x y => match of' (t:=Tbase t) x with
+ | Some x' => R t x' y
+ | None => True
+ end.
+
+ Lemma lift_relation_flat_type_pointwise t x y x'
+ (Hx : of' x = Some x')
+ : interp_flat_type_rel_pointwise lift_relation x y
+ <-> interp_flat_type_rel_pointwise (t:=t) R x' y.
+ Proof.
+ induction t; simpl; try tauto.
+ { unfold lift_relation; rewrite Hx; reflexivity. }
+ { rewrite of'_pair in Hx.
+ destruct (of' (fst x)) eqn:?, (of' (snd x)) eqn:?; try congruence.
+ inversion_option; subst.
+ destruct_head_hnf prod; split_iff; intuition eauto. }
+ Qed.
+
+ Lemma lift_relation_type_pointwise t f g f'
+ (Hx : forall x x', of' x = Some x' -> of' (f x) = Some (f' x'))
+ : interp_type_rel_pointwise lift_relation f g
+ -> interp_type_rel_pointwise (t:=t) R f' g.
+ Proof.
+ destruct t; simpl; unfold Morphisms.respectful_hetero.
+ intros H x y p; specialize (H (to' (Some x)) y).
+ eapply lift_relation_flat_type_pointwise in p; [ | apply of'_to'.. ].
+ specialize (H p).
+ eapply lift_relation_flat_type_pointwise in H; [ exact H | ].
+ erewrite Hx; [ reflexivity | ].
+ rewrite of'_to'; reflexivity.
+ Qed.
+ End lift_relation.
End lift_option.
Global Arguments of' {T t} _.
Global Arguments to' {T t} _.
- Global Arguments Some {T t} _.
Global Arguments lift_relation {T _} R _ _ _.
Section lift_option2.
- Context (T U : Type).
- Definition lift_relation2 (R : T -> U -> Prop)
+ Context (T U : Type) (R : T -> U -> Prop).
+ Definition lift_relation2
: forall t, interp_base_type' T t -> interp_base_type' U t -> Prop
:= fun t x y => match of' (t:=Tbase t) x, of' (t:=Tbase t) y with
| Datatypes.Some x', Datatypes.Some y' => R x' y'
| None, None => True
| _, _ => False
end.
+
+ Lemma lift_relation2_flat_type_pointwise t x y x' y'
+ (Hx : of' x = Datatypes.Some x')
+ (Hy : of' y = Datatypes.Some y')
+ : interp_flat_type_rel_pointwise lift_relation2 x y
+ <-> interp_flat_type_rel_pointwise (t:=t) (fun _ => R) x' y'.
+ Proof.
+ induction t; simpl; try tauto.
+ { unfold lift_relation2; rewrite Hx, Hy; reflexivity. }
+ { rewrite of'_pair in Hx, Hy.
+ destruct (of' (fst x)) eqn:?, (of' (snd x)) eqn:?; try congruence.
+ destruct (of' (fst y)) eqn:?, (of' (snd y)) eqn:?; try congruence.
+ inversion_option; subst.
+ destruct_head_hnf prod; split_iff; intuition eauto. }
+ Qed.
+
+ Lemma lift_relation2_type_pointwise t f g f' g'
+ (Hx : forall x x', of' x = Datatypes.Some x' -> of' (f x) = Datatypes.Some (f' x'))
+ (Hy : forall x x', of' x = Datatypes.Some x' -> of' (g x) = Datatypes.Some (g' x'))
+ : interp_type_rel_pointwise lift_relation2 f g
+ -> interp_type_rel_pointwise (t:=t) (fun _ => R) f' g'.
+ Proof.
+ destruct t; simpl; unfold Morphisms.respectful_hetero.
+ intros H x y p; specialize (H (to' (Datatypes.Some x)) (to' (Datatypes.Some y))).
+ eapply lift_relation2_flat_type_pointwise in p; [ | apply of'_to'.. ].
+ specialize (H p).
+ eapply lift_relation2_flat_type_pointwise in H; [ exact H | .. ];
+ [ erewrite Hx; [ reflexivity | ]
+ | erewrite Hy; [ reflexivity | ] ];
+ rewrite of'_to'; reflexivity.
+ Qed.
End lift_option2.
Global Arguments lift_relation2 {T U} R _ _ _.
End LiftOption.
@@ -271,17 +343,18 @@ Module InterpretationsGen (Bit : BitSize).
end.
Definition interp_op {src dst} (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst
:= match f in op src dst return interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst with
- | OpConst v => fun _ => ZToWordW v
- | Add => fun xy => fst xy + snd xy
- | Sub => fun xy => fst xy - snd xy
- | Mul => fun xy => fst xy * snd xy
- | Shl => fun xy => fst xy << snd xy
- | Shr => fun xy => fst xy >> snd xy
- | Land => fun xy => land (fst xy) (snd xy)
- | Lor => fun xy => lor (fst xy) (snd xy)
- | Neg int_width => fun x => neg int_width x
- | Cmovne => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
- | Cmovle => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | OpConst TZ v => fun _ => ZToWordW v
+ | Add TZ => fun xy => fst xy + snd xy
+ | Sub TZ => fun xy => fst xy - snd xy
+ | Mul TZ => fun xy => fst xy * snd xy
+ | Shl TZ => fun xy => fst xy << snd xy
+ | Shr TZ => fun xy => fst xy >> snd xy
+ | Land TZ => fun xy => land (fst xy) (snd xy)
+ | Lor TZ => fun xy => lor (fst xy) (snd xy)
+ | Neg TZ int_width => fun x => neg int_width x
+ | Cmovne TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
+ | Cmovle TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | Cast TZ TZ => fun x => x
end%wordW.
Definition of_Z ty : Z.interp_base_type ty -> interp_base_type ty
@@ -416,20 +489,21 @@ Module InterpretationsGen (Bit : BitSize).
End Notations.
Definition interp_base_type (ty : base_type) : Type
- := LiftOption.interp_base_type' bounds ty.
+ := option bounds.
Definition interp_op {src dst} (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst
:= match f in op src dst return interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst with
- | OpConst v => fun _ => SmartBuildBounds v v
- | Add => fun xy => fst xy + snd xy
- | Sub => fun xy => fst xy - snd xy
- | Mul => fun xy => fst xy * snd xy
- | Shl => fun xy => fst xy << snd xy
- | Shr => fun xy => fst xy >> snd xy
- | Land => fun xy => land (fst xy) (snd xy)
- | Lor => fun xy => lor (fst xy) (snd xy)
- | Neg int_width => fun x => neg int_width x
- | Cmovne => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
- | Cmovle => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | OpConst TZ v => fun _ => SmartBuildBounds v v
+ | Add _ => fun xy => fst xy + snd xy
+ | Sub _ => fun xy => fst xy - snd xy
+ | Mul _ => fun xy => fst xy * snd xy
+ | Shl _ => fun xy => fst xy << snd xy
+ | Shr _ => fun xy => fst xy >> snd xy
+ | Land _ => fun xy => land (fst xy) (snd xy)
+ | Lor _ => fun xy => lor (fst xy) (snd xy)
+ | Neg _ int_width => fun x => neg int_width x
+ | Cmovne _ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
+ | Cmovle _ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | Cast _ _ => fun x => x
end%bounds.
Definition of_wordW ty : WordW.interp_base_type ty -> interp_base_type ty
@@ -804,17 +878,18 @@ Module InterpretationsGen (Bit : BitSize).
Definition interp_op {src dst} (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst
:= match f in op src dst return interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst with
- | OpConst v => fun _ => SmartBuildBoundedWord v
- | Add => fun xy => fst xy + snd xy
- | Sub => fun xy => fst xy - snd xy
- | Mul => fun xy => fst xy * snd xy
- | Shl => fun xy => fst xy << snd xy
- | Shr => fun xy => fst xy >> snd xy
- | Land => fun xy => land (fst xy) (snd xy)
- | Lor => fun xy => lor (fst xy) (snd xy)
- | Neg int_width => fun x => neg int_width x
- | Cmovne => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
- | Cmovle => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | OpConst TZ v => fun _ => SmartBuildBoundedWord v
+ | Add TZ => fun xy => fst xy + snd xy
+ | Sub TZ => fun xy => fst xy - snd xy
+ | Mul TZ => fun xy => fst xy * snd xy
+ | Shl TZ => fun xy => fst xy << snd xy
+ | Shr TZ => fun xy => fst xy >> snd xy
+ | Land TZ => fun xy => land (fst xy) (snd xy)
+ | Lor TZ => fun xy => lor (fst xy) (snd xy)
+ | Neg TZ int_width => fun x => neg int_width x
+ | Cmovne TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
+ | Cmovle TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovle x y z w
+ | Cast TZ TZ => fun x => x
end%bounded_word.
End BoundedWordW.
diff --git a/src/Reflection/Z/JavaNotations.v b/src/Reflection/Z/JavaNotations.v
index 4a33a6330..8dc23ec82 100644
--- a/src/Reflection/Z/JavaNotations.v
+++ b/src/Reflection/Z/JavaNotations.v
@@ -40,18 +40,18 @@ Notation "'(int)' x" := (Op (Cast _ (TWord 5)) (Var x)).
Notation "'M32' & x" := (Op (Cast _ (TWord 6)) (Var x)).
Notation "'(uint128_t)' x" := (Op (Cast _ (TWord 7)) (Var x)).
*)
-Notation "x + y" := (Op (Add) (Pair x y)).
-Notation "x + y" := (Op (Add) (Pair (Var x) y)).
-Notation "x + y" := (Op (Add) (Pair x (Var y))).
-Notation "x + y" := (Op (Add) (Pair (Var x) (Var y))).
-Notation "x - y" := (Op (Sub) (Pair x y)).
-Notation "x - y" := (Op (Sub) (Pair (Var x) y)).
-Notation "x - y" := (Op (Sub) (Pair x (Var y))).
-Notation "x - y" := (Op (Sub) (Pair (Var x) (Var y))).
-Notation "x * y" := (Op (Mul) (Pair x y)).
-Notation "x * y" := (Op (Mul) (Pair (Var x) y)).
-Notation "x * y" := (Op (Mul) (Pair x (Var y))).
-Notation "x * y" := (Op (Mul) (Pair (Var x) (Var y))).
+Notation "x + y" := (Op (Add _) (Pair x y)).
+Notation "x + y" := (Op (Add _) (Pair (Var x) y)).
+Notation "x + y" := (Op (Add _) (Pair x (Var y))).
+Notation "x + y" := (Op (Add _) (Pair (Var x) (Var y))).
+Notation "x - y" := (Op (Sub _) (Pair x y)).
+Notation "x - y" := (Op (Sub _) (Pair (Var x) y)).
+Notation "x - y" := (Op (Sub _) (Pair x (Var y))).
+Notation "x - y" := (Op (Sub _) (Pair (Var x) (Var y))).
+Notation "x * y" := (Op (Mul _) (Pair x y)).
+Notation "x * y" := (Op (Mul _) (Pair (Var x) y)).
+Notation "x * y" := (Op (Mul _) (Pair x (Var y))).
+Notation "x * y" := (Op (Mul _) (Pair (Var x) (Var y))).
(* python:
<<
for opn, op in (('*', 'Mul'), ('+', 'Add'), ('&', 'Land')):
@@ -115,20 +115,18 @@ Notation "x + y" := (Op (Add (TWord 7)) (Pair x (Op (Cast _ (TWord 7)) (Var y)))
Notation "x + y" := (Op (Add (TWord 7)) (Pair (Var x) (Op (Cast _ (TWord 7)) y))).
Notation "x + y" := (Op (Add (TWord 7)) (Pair (Var x) (Op (Cast _ (TWord 7)) (Var y)))).
*)
-Notation "x >>> y" := (Op (Shr) (Pair x y)).
-Notation "x >>> y" := (Op (Shr) (Pair (Var x) y)).
-Notation "x >>> y" := (Op (Shr) (Pair x (Var y))).
-Notation "x >>> y" := (Op (Shr) (Pair (Var x) (Var y))).
-(*
+Notation "x >>> y" := (Op (Shr _) (Pair x y)).
+Notation "x >>> y" := (Op (Shr _) (Pair (Var x) y)).
+Notation "x >>> y" := (Op (Shr _) (Pair x (Var y))).
+Notation "x >>> y" := (Op (Shr _) (Pair (Var x) (Var y))).
Notation "x >>> y" := (Op (Shr _) (Pair x (Op (Cast _ _) y))).
Notation "x >>> y" := (Op (Shr _) (Pair (Var x) (Op (Cast _ _) y))).
Notation "x >>> y" := (Op (Shr _) (Pair x (Op (Cast _ _) (Var y)))).
Notation "x >>> y" := (Op (Shr _) (Pair (Var x) (Op (Cast _ _) (Var y)))).
-*)
-Notation "x & y" := (Op (Land) (Pair x y)).
-Notation "x & y" := (Op (Land) (Pair (Var x) y)).
-Notation "x & y" := (Op (Land) (Pair x (Var y))).
-Notation "x & y" := (Op (Land) (Pair (Var x) (Var y))).
+Notation "x & y" := (Op (Land _) (Pair x y)).
+Notation "x & y" := (Op (Land _) (Pair (Var x) y)).
+Notation "x & y" := (Op (Land _) (Pair x (Var y))).
+Notation "x & y" := (Op (Land _) (Pair (Var x) (Var y))).
(*
Notation "x & y" := (Op (Land (TWord 6)) (Pair (Op (Cast _ (TWord 6)) x) y)).
Notation "x & y" := (Op (Land (TWord 6)) (Pair (Op (Cast _ (TWord 6)) x) (Var y))).
diff --git a/src/Reflection/Z/OpInversion.v b/src/Reflection/Z/OpInversion.v
index 3ef7b7e5a..6b2cdd85b 100644
--- a/src/Reflection/Z/OpInversion.v
+++ b/src/Reflection/Z/OpInversion.v
@@ -19,9 +19,9 @@ Ltac invert_op := repeat invert_op_step.
Ltac invert_match_op_step :=
match goal with
- | [ |- appcontext[match ?e with OpConst _ => _ | _ => _ end] ]
+ | [ |- appcontext[match ?e with OpConst _ _ => _ | _ => _ end] ]
=> invert_one_op e
- | [ H : appcontext[match ?e with OpConst _ => _ | _ => _ end] |- _ ]
+ | [ H : appcontext[match ?e with OpConst _ _ => _ | _ => _ end] |- _ ]
=> invert_one_op e
end.
diff --git a/src/Reflection/Z/Reify.v b/src/Reflection/Z/Reify.v
index e200b2e9e..84bc6f078 100644
--- a/src/Reflection/Z/Reify.v
+++ b/src/Reflection/Z/Reify.v
@@ -10,22 +10,24 @@ Require Import Crypto.Reflection.Inline.
Require Import Crypto.Reflection.InlineInterp.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.LinearizeInterp.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Ltac base_reify_op op op_head extra ::=
lazymatch op_head with
- | @Z.add => constr:(reify_op op op_head 2 Add)
- | @Z.mul => constr:(reify_op op op_head 2 Mul)
- | @Z.sub => constr:(reify_op op op_head 2 Sub)
- | @Z.shiftl => constr:(reify_op op op_head 2 Shl)
- | @Z.shiftr => constr:(reify_op op op_head 2 Shr)
- | @Z.land => constr:(reify_op op op_head 2 Land)
- | @Z.lor => constr:(reify_op op op_head 2 Lor)
- | @ModularBaseSystemListZOperations.cmovne => constr:(reify_op op op_head 4 Cmovne)
- | @ModularBaseSystemListZOperations.cmovl => constr:(reify_op op op_head 4 Cmovle)
+ | @Z.add => constr:(reify_op op op_head 2 (Add TZ))
+ | @Z.mul => constr:(reify_op op op_head 2 (Mul TZ))
+ | @Z.sub => constr:(reify_op op op_head 2 (Sub TZ))
+ | @Z.shiftl => constr:(reify_op op op_head 2 (Shl TZ))
+ | @Z.shiftr => constr:(reify_op op op_head 2 (Shr TZ))
+ | @Z.land => constr:(reify_op op op_head 2 (Land TZ))
+ | @Z.lor => constr:(reify_op op op_head 2 (Lor TZ))
+ | @ModularBaseSystemListZOperations.cmovne => constr:(reify_op op op_head 4 (Cmovne TZ))
+ | @ModularBaseSystemListZOperations.cmovl => constr:(reify_op op op_head 4 (Cmovle TZ))
| @ModularBaseSystemListZOperations.neg
=> lazymatch extra with
| @ModularBaseSystemListZOperations.neg ?int_width _
- => constr:(reify_op op op_head 1 (Neg int_width))
+ => constr:(reify_op op op_head 1 (Neg TZ int_width))
| _ => fail 100 "Anomaly: In Reflection.Z.base_reify_op: head is neg but body is wrong:" extra
end
end.
@@ -36,12 +38,13 @@ Ltac base_reify_type T ::=
Ltac Reify' e := Reflection.Reify.Reify' base_type interp_base_type op e.
Ltac Reify e :=
let v := Reflection.Reify.Reify base_type interp_base_type op make_const e in
- constr:((*Inline _*) ((*CSE _*) (InlineConst is_const (Linearize v)))).
-Ltac prove_InlineConst_Linearize_Compile_correct :=
+ constr:(ExprEta ((*Inline _*) ((*CSE _*) (InlineConst is_const (Linearize v))))).
+Ltac prove_ExprEta_InlineConst_Linearize_Compile_correct :=
fun _
=> intros;
+ rewrite ?InterpExprEta;
lazymatch goal with
- | [ |- ?R (@Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op ?t (InlineConst ?is_const (Linearize _))) _ ]
+ | [ |- ?R (@Syntax.Interp ?base_type_code ?interp_base_type ?op ?interp_op ?t (InlineConst ?is_const (Linearize _)) ?x) _ ]
=> etransitivity;
[ apply (@InterpInlineConst base_type_code interp_base_type op interp_op is_const t);
reflect_Wf base_type_eq_semidec_is_dec op_beq_bl
@@ -50,4 +53,4 @@ Ltac prove_InlineConst_Linearize_Compile_correct :=
| prove_compile_correct () ] ]
end.
Ltac Reify_rhs :=
- Reflection.Reify.Reify_rhs_gen Reify prove_InlineConst_Linearize_Compile_correct interp_op ltac:(fun tac => tac ()).
+ Reflection.Reify.Reify_rhs_gen Reify prove_ExprEta_InlineConst_Linearize_Compile_correct interp_op ltac:(fun tac => tac ()).
diff --git a/src/Reflection/Z/Syntax.v b/src/Reflection/Z/Syntax.v
index 2060c6852..9b009386c 100644
--- a/src/Reflection/Z/Syntax.v
+++ b/src/Reflection/Z/Syntax.v
@@ -16,17 +16,18 @@ Definition interp_base_type (v : base_type) : Type :=
end.
Inductive op : flat_type base_type -> flat_type base_type -> Type :=
-| OpConst (z : Z) : op Unit tZ
-| Add : op (tZ * tZ) tZ
-| Sub : op (tZ * tZ) tZ
-| Mul : op (tZ * tZ) tZ
-| Shl : op (tZ * tZ) tZ
-| Shr : op (tZ * tZ) tZ
-| Land : op (tZ * tZ) tZ
-| Lor : op (tZ * tZ) tZ
-| Neg (int_width : Z) : op tZ tZ
-| Cmovne : op (tZ * tZ * tZ * tZ) tZ
-| Cmovle : op (tZ * tZ * tZ * tZ) tZ.
+| OpConst {T} (z : interp_base_type T) : op Unit (Tbase T)
+| Add T : op (Tbase T * Tbase T) (Tbase T)
+| Sub T : op (Tbase T * Tbase T) (Tbase T)
+| Mul T : op (Tbase T * Tbase T) (Tbase T)
+| Shl T : op (Tbase T * Tbase T) (Tbase T)
+| Shr T : op (Tbase T * Tbase T) (Tbase T)
+| Land T : op (Tbase T * Tbase T) (Tbase T)
+| Lor T : op (Tbase T * Tbase T) (Tbase T)
+| Neg T (int_width : Z) : op (Tbase T) (Tbase T)
+| Cmovne T : op (Tbase T * Tbase T * Tbase T * Tbase T) (Tbase T)
+| Cmovle T : op (Tbase T * Tbase T * Tbase T * Tbase T) (Tbase T)
+| Cast T1 T2 : op (Tbase T1) (Tbase T2).
Definition interpToZ {t} : interp_base_type t -> Z
:= match t with
@@ -45,15 +46,16 @@ Local Notation eta4 x := (eta3 (fst x), snd x).
Definition interp_op src dst (f : op src dst) : interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst
:= match f in op src dst return interp_flat_type interp_base_type src -> interp_flat_type interp_base_type dst with
- | OpConst v => fun _ => v
- | Add => fun xy => fst xy + snd xy
- | Sub => fun xy => fst xy - snd xy
- | Mul => fun xy => fst xy * snd xy
- | Shl => fun xy => Z.shiftl (fst xy) (snd xy)
- | Shr => fun xy => Z.shiftr (fst xy) (snd xy)
- | Land => fun xy => Z.land (fst xy) (snd xy)
- | Lor => fun xy => Z.lor (fst xy) (snd xy)
- | Neg int_width => fun x => ModularBaseSystemListZOperations.neg int_width x
- | Cmovne => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
- | Cmovle => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovl x y z w
+ | OpConst _ v => fun _ => v
+ | Add TZ => fun xy => fst xy + snd xy
+ | Sub TZ => fun xy => fst xy - snd xy
+ | Mul TZ => fun xy => fst xy * snd xy
+ | Shl TZ => fun xy => Z.shiftl (fst xy) (snd xy)
+ | Shr TZ => fun xy => Z.shiftr (fst xy) (snd xy)
+ | Land TZ => fun xy => Z.land (fst xy) (snd xy)
+ | Lor TZ => fun xy => Z.lor (fst xy) (snd xy)
+ | Neg TZ int_width => fun x => ModularBaseSystemListZOperations.neg int_width x
+ | Cmovne TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovne x y z w
+ | Cmovle TZ => fun xyzw => let '(x, y, z, w) := eta4 xyzw in cmovl x y z w
+ | Cast _ _ => cast_const
end%Z.
diff --git a/src/Reflection/Z/Syntax/Equality.v b/src/Reflection/Z/Syntax/Equality.v
index 3043deae1..ff3ed9b67 100644
--- a/src/Reflection/Z/Syntax/Equality.v
+++ b/src/Reflection/Z/Syntax/Equality.v
@@ -1,10 +1,15 @@
Require Import Coq.ZArith.ZArith.
Require Import Crypto.Reflection.Syntax.
+Require Import Crypto.Reflection.TypeInversion.
Require Import Crypto.Reflection.Equality.
Require Import Crypto.Reflection.Z.Syntax.
Require Import Crypto.Util.Decidable.
Require Import Crypto.Util.PartiallyReifiedProp.
Require Import Crypto.Util.HProp.
+Require Import Crypto.Util.Tactics.BreakMatch.
+Require Import Crypto.Util.Tactics.DestructHead.
+Require Import Crypto.Util.FixedWordSizesEquality.
+Require Import Crypto.Util.NatUtil.
Global Instance dec_eq_base_type : DecidableRel (@eq base_type)
:= base_type_eq_dec.
@@ -13,46 +18,69 @@ Global Instance dec_eq_type : DecidableRel (@eq (type base_type)) := _.
Definition base_type_eq_semidec_transparent (t1 t2 : base_type)
: option (t1 = t2)
- := Some (match t1, t2 return t1 = t2 with
- | TZ, TZ => eq_refl
- end).
+ := match base_type_eq_dec t1 t2 with
+ | left pf => Some pf
+ | right _ => None
+ end.
Lemma base_type_eq_semidec_is_dec t1 t2 : base_type_eq_semidec_transparent t1 t2 = None -> t1 <> t2.
Proof.
- unfold base_type_eq_semidec_transparent; congruence.
+ unfold base_type_eq_semidec_transparent; break_match; congruence.
Qed.
-Definition op_beq_hetero {t1 tR t1' tR'} (f : op t1 tR) (g : op t1' tR') : reified_Prop
+Definition op_beq_hetero {t1 tR t1' tR'} (f : op t1 tR) (g : op t1' tR') : bool
:= match f, g return bool with
- | OpConst v, OpConst v' => Z.eqb v v'
- | OpConst _, _ => false
- | Add, Add => true
- | Add, _ => false
- | Sub, Sub => true
- | Sub, _ => false
- | Mul, Mul => true
- | Mul, _ => false
- | Shl, Shl => true
- | Shl, _ => false
- | Shr, Shr => true
- | Shr, _ => false
- | Land, Land => true
- | Land, _ => false
- | Lor, Lor => true
- | Lor, _ => false
- | Neg n, Neg m => Z.eqb n m
- | Neg _, _ => false
- | Cmovne, Cmovne => true
- | Cmovne, _ => false
- | Cmovle, Cmovle => true
- | Cmovle, _ => false
- end.
+ | OpConst TZ v, OpConst TZ v' => Z.eqb v v'
+ | OpConst _ _, _ => false
+ | Add T1, Add T2
+ | Sub T1, Sub T2
+ | Mul T1, Mul T2
+ | Shl T1, Shl T2
+ | Shr T1, Shr T2
+ | Land T1, Land T2
+ | Lor T1, Lor T2
+ | Cmovne T1, Cmovne T2
+ | Cmovle T1, Cmovle T2
+ => base_type_beq T1 T2
+ | Neg T1 n, Neg T2 m
+ => base_type_beq T1 T2 && Z.eqb n m
+ | Cast T1 T2, Cast T1' T2'
+ => base_type_beq T1 T1' && base_type_beq T2 T2'
+ | Add _, _ => false
+ | Sub _, _ => false
+ | Mul _, _ => false
+ | Shl _, _ => false
+ | Shr _, _ => false
+ | Land _, _ => false
+ | Lor _, _ => false
+ | Neg _ _, _ => false
+ | Cmovne _, _ => false
+ | Cmovle _, _ => false
+ | Cast _ _, _ => false
+ end%bool.
-Definition op_beq t1 tR (f g : op t1 tR) : reified_Prop
+Definition op_beq t1 tR (f g : op t1 tR) : bool
:= Eval cbv [op_beq_hetero] in op_beq_hetero f g.
Definition op_beq_hetero_type_eq {t1 tR t1' tR'} f g : to_prop (@op_beq_hetero t1 tR t1' tR' f g) -> t1 = t1' /\ tR = tR'.
Proof.
- destruct f, g; simpl; try solve [ repeat constructor | intros [] ].
+ destruct f, g;
+ repeat match goal with
+ | _ => progress unfold op_beq_hetero in *
+ | _ => simpl; intro; exfalso; assumption
+ | _ => solve [ repeat constructor ]
+ | _ => progress destruct_head base_type
+ | [ |- context[reified_Prop_of_bool ?b] ]
+ => let H := fresh in destruct (Sumbool.sumbool_of_bool b) as [H|H]; rewrite H
+ | [ H : nat_beq _ _ = true |- _ ] => apply internal_nat_dec_bl in H; subst
+ | [ H : wordT_beq_hetero _ _ = true |- _ ] => apply wordT_beq_bl in H; subst
+ | [ H : wordT_beq_hetero _ _ = true |- _ ] => apply wordT_beq_hetero_bl in H; destruct H; subst
+ | [ H : andb ?x ?y = true |- _ ]
+ => assert (x = true /\ y = true) by (destruct x, y; simpl in *; repeat constructor; exfalso; clear -H; abstract congruence);
+ clear H
+ | [ H : and _ _ |- _ ] => destruct H
+ | [ H : false = true |- _ ] => exfalso; clear -H; abstract congruence
+ | [ H : true = false |- _ ] => exfalso; clear -H; abstract congruence
+ end.
Defined.
Definition op_beq_hetero_type_eqs {t1 tR t1' tR'} f g : to_prop (@op_beq_hetero t1 tR t1' tR' f g) -> t1 = t1'
@@ -68,22 +96,29 @@ Definition op_beq_hetero_eq {t1 tR t1' tR'} f g
_ (op_beq_hetero_type_eqs f g pf)
= g.
Proof.
- destruct f, g; simpl; try solve [ reflexivity | intros [] ];
- unfold op_beq_hetero; simpl;
- repeat match goal with
- | [ |- context[to_prop (reified_Prop_of_bool ?x)] ]
- => destruct (Sumbool.sumbool_of_bool x) as [P|P]
- | [ H : NatUtil.nat_beq _ _ = true |- _ ]
- => apply NatUtil.internal_nat_dec_bl in H
- | [ H : Z.eqb _ _ = true |- _ ]
- => apply Z.eqb_eq in H
- | _ => progress subst
- | _ => reflexivity
- | [ H : ?x = false |- context[reified_Prop_of_bool ?x] ]
- => rewrite H
- | _ => progress simpl @to_prop
- | _ => tauto
- end.
+ destruct f, g;
+ repeat match goal with
+ | _ => solve [ intros [] ]
+ | _ => reflexivity
+ | [ H : False |- _ ] => exfalso; assumption
+ | _ => intro
+ | [ |- context[op_beq_hetero_type_eqd ?f ?g ?pf] ]
+ => generalize (op_beq_hetero_type_eqd f g pf), (op_beq_hetero_type_eqs f g pf)
+ | _ => intro
+ | _ => progress eliminate_hprop_eq
+ | _ => progress inversion_flat_type
+ | _ => progress unfold op_beq_hetero in *
+ | _ => progress simpl in *
+ | [ H : context[andb ?x ?y] |- _ ]
+ => destruct x eqn:?, y eqn:?; simpl in H
+ | [ H : Z.eqb _ _ = true |- _ ] => apply Z.eqb_eq in H
+ | [ H : to_prop (reified_Prop_of_bool ?b) |- _ ] => destruct b eqn:?; compute in H
+ | _ => progress subst
+ | _ => progress break_match_hyps
+ | [ H : wordT_beq_hetero _ _ = true |- _ ] => apply wordT_beq_bl in H; subst
+ | [ H : wordT_beq_hetero _ _ = true |- _ ] => apply wordT_beq_hetero_bl in H; destruct H; subst
+ | _ => congruence
+ end.
Qed.
Lemma op_beq_bl : forall t1 tR x y, to_prop (op_beq t1 tR x y) -> x = y.
diff --git a/src/Reflection/Z/Syntax/Util.v b/src/Reflection/Z/Syntax/Util.v
index 42569daf8..1d591658f 100644
--- a/src/Reflection/Z/Syntax/Util.v
+++ b/src/Reflection/Z/Syntax/Util.v
@@ -1,4 +1,5 @@
Require Import Crypto.Reflection.Syntax.
+Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.TypeUtil.
Require Import Crypto.Reflection.TypeInversion.
Require Import Crypto.Reflection.Z.Syntax.
@@ -9,17 +10,85 @@ Require Import Crypto.Util.Tactics.DestructHead.
Require Import Crypto.Util.Notations.
Definition make_const t : interp_base_type t -> op Unit (Tbase t)
- := match t with TZ => OpConst end.
+ := OpConst.
Definition is_const s d (v : op s d) : bool
- := match v with OpConst _ => true | _ => false end.
+ := match v with OpConst _ _ => true | _ => false end.
Arguments is_const [s d] v.
Definition is_cast s d (v : op s d) : bool
- := false.
+ := match v with Cast _ _ => true | _ => false end.
Arguments is_cast [s d] v.
Definition base_type_leb (v1 v2 : base_type) : bool
- := true.
+ := match v1, v2 with
+ | _, TZ => true
+ end.
Definition base_type_min := base_type_min base_type_leb.
Global Arguments base_type_min !_ !_ / .
Global Arguments TypeUtil.base_type_min _ _ _ / .
+
+Definition Castb {var} A A' (v : exprf base_type op (var:=var) (Tbase A))
+ : exprf base_type op (var:=var) (Tbase A')
+ := Op (Cast A A') v.
+
+Local Notation Se opv := (Some (existT _ (_, _) opv)) (only parsing).
+
+Definition genericize_op src dst (opc : op src dst) (t_in t_out : base_type)
+ : option { src'dst' : _ & op (fst src'dst') (snd src'dst') }
+ := match opc with
+ | OpConst T z => Se (OpConst z)
+ | Add T => Se (Add t_out)
+ | Sub T => Se (Sub t_in)
+ | Mul T => Se (Mul t_out)
+ | Shl T => Se (Shl t_out)
+ | Shr T => Se (Shr t_in)
+ | Land T => Se (Land t_out)
+ | Lor T => Se (Lor t_out)
+ | Neg T int_width => Se (Neg t_out int_width)
+ | Cmovne T => Se (Cmovne t_out)
+ | Cmovle T => Se (Cmovle t_out)
+ | Cast T1 T2 => None
+ end.
+
+Lemma cast_const_id {t} v
+ : @cast_const t t v = v.
+Proof.
+ destruct t; simpl; trivial.
+Qed.
+
+Lemma cast_const_idempotent {a b c} v
+ : base_type_min b (base_type_min a c) = base_type_min a c
+ -> @cast_const b c (@cast_const a b v) = @cast_const a c v.
+Proof.
+ repeat first [ reflexivity
+ | congruence
+ | progress destruct_head' base_type
+ | progress simpl
+ | progress break_match
+ | progress subst
+ | intro
+ | match goal with
+ | [ H : ?leb _ _ = true |- _ ] => apply Compare_dec.leb_complete in H
+ | [ H : ?leb _ _ = false |- _ ] => apply Compare_dec.leb_iff_conv in H
+ end
+ | rewrite ZToWord_wordToZ_ZToWord by omega *
+ | rewrite wordToZ_ZToWord_wordToZ by omega * ].
+Qed.
+
+Lemma is_cast_correct s d opc
+ : forall e,
+ @is_cast (Tbase s) (Tbase d) opc = true
+ -> Syntax.interp_op _ _ opc (interpf Syntax.interp_op e)
+ = interpf Syntax.interp_op (Castb s d e).
+Proof.
+ preinvert_one_type opc; intros ? opc.
+ pose (fun x y => op y x) as op'.
+ change op with (fun x y => op' y x) in opc; cbv beta in opc.
+ preinvert_one_type opc; intros ? opc; subst op'; cbv beta in *.
+ destruct opc; try exact I; simpl; try congruence.
+Qed.
+
+Lemma wff_Castb {var1 var2 G A A'} {e1 e2 : exprf base_type op (Tbase A)}
+ (Hwf : wff (var1:=var1) (var2:=var2) G e1 e2)
+ : wff G (Castb A A' e1) (Castb A A' e2).
+Proof. constructor; assumption. Qed.
diff --git a/src/Specific/FancyMachine256/Barrett.v b/src/Specific/FancyMachine256/Barrett.v
index 93a9432aa..a43becf68 100644
--- a/src/Specific/FancyMachine256/Barrett.v
+++ b/src/Specific/FancyMachine256/Barrett.v
@@ -63,9 +63,11 @@ End expression.
Section reflected.
Context (ops : fancy_machine.instructions (2 * 128)).
- Definition rexpression : Syntax.Expr base_type op (Arrow TZ (Arrow TZ (Arrow TW (Arrow TW (Tbase TW))))).
+ Local Notation tZ := (Tbase TZ).
+ Local Notation tW := (Tbase TW).
+ Definition rexpression : Syntax.Expr base_type op (Arrow (tZ * tZ * tW * tW) tW).
Proof.
- let v := (eval cbv beta delta [expression] in (fun m μ x y => expression ops m μ (x, y))) in
+ let v := (eval cbv beta delta [expression] in (fun mμxy => let '(mv, μv, xv, yv) := mμxy in expression ops mv μv (xv, yv))) in
let v := Reify v in
exact v.
Defined.
@@ -85,8 +87,8 @@ Section reflected.
Context (m μ : Z)
(props : fancy_machine.arithmetic ops).
- Let result (v : Tuple.tuple fancy_machine.W 2) := Syntax.Interp interp_op rexpression_simple m μ (fst v) (snd v).
- Let assembled_result (v : Tuple.tuple fancy_machine.W 2) : fancy_machine.W := Core.Interp compiled_syntax m μ (fst v) (snd v).
+ Let result (v : Tuple.tuple fancy_machine.W 2) := Syntax.Interp (@interp_op _) rexpression_simple (m, μ, fst v, snd v).
+ Let assembled_result (v : Tuple.tuple fancy_machine.W 2) : fancy_machine.W := Core.Interp compiled_syntax (m, μ, fst v, snd v).
Theorem sanity : result = expression ops m μ.
Proof.
@@ -126,7 +128,7 @@ End reflected.
Print compiled_syntax.
(* compiled_syntax =
fun ops : fancy_machine.instructions (2 * 128) =>
-λn RegMod RegMuLow x xHigh,
+λn (RegMod, RegMuLow, x, xHigh),
slet RegMod := RegMod in
slet RegMuLow := RegMuLow in
slet RegZero := ldi 0 in
@@ -148,5 +150,6 @@ c.Sub(tmp, x, tmp),
c.Addm(q, tmp, RegZero),
c.Addm(out, q, RegZero),
Return out
- : forall ops : fancy_machine.instructions (2 * 128), expr base_type op Register (TZ -> TZ -> TW -> TW -> Tbase TW)
+ : forall ops : fancy_machine.instructions (2 * 128),
+ expr base_type op Register (Tbase TZ * Tbase TZ * Tbase TW * Tbase TW -> Tbase TW)
*)
diff --git a/src/Specific/FancyMachine256/Montgomery.v b/src/Specific/FancyMachine256/Montgomery.v
index f0ca09119..fd0d9a57f 100644
--- a/src/Specific/FancyMachine256/Montgomery.v
+++ b/src/Specific/FancyMachine256/Montgomery.v
@@ -53,9 +53,13 @@ End expression.
Section reflected.
Context (ops : fancy_machine.instructions (2 * 128)).
- Definition rexpression : Syntax.Expr base_type op (Arrow TZ (Arrow TZ (Arrow TW (Arrow TW (Tbase TW))))).
+ Local Notation tZ := (Tbase TZ).
+ Local Notation tW := (Tbase TW).
+ Definition rexpression : Syntax.Expr base_type op (Arrow (tZ * tZ * tW * tW) tW).
Proof.
- let v := (eval cbv beta delta [expression] in (fun modulus m' x y => expression ops modulus m' (x, y))) in
+ let v := (eval cbv beta delta [expression] in
+ (fun modulus_m'_x_y => let '(modulusv, m'v, xv, yv) := modulus_m'_x_y in
+ expression ops modulusv m'v (xv, yv))) in
let v := Reify v in
exact v.
Defined.
@@ -76,9 +80,9 @@ Section reflected.
Context (modulus m' : Z)
(props : fancy_machine.arithmetic ops).
- Let result (v : Tuple.tuple fancy_machine.W 2) := Syntax.Interp interp_op rexpression_simple modulus m' (fst v) (snd v).
+ Let result (v : Tuple.tuple fancy_machine.W 2) := Syntax.Interp interp_op rexpression_simple (modulus, m', fst v, snd v).
- Let assembled_result (v : Tuple.tuple fancy_machine.W 2) : fancy_machine.W := Core.Interp compiled_syntax modulus m' (fst v) (snd v).
+ Let assembled_result (v : Tuple.tuple fancy_machine.W 2) : fancy_machine.W := Core.Interp compiled_syntax (modulus, m', fst v, snd v).
Theorem sanity : result = expression ops modulus m'.
Proof.
@@ -124,7 +128,7 @@ End reflected.
Print compiled_syntax.
(* compiled_syntax =
fun ops : fancy_machine.instructions (2 * 128) =>
-λn RegMod RegPInv lo hi,
+λn (RegMod, RegPInv, lo, hi),
slet RegMod := RegMod in
slet RegPInv := RegPInv in
slet RegZero := ldi 0 in
@@ -147,5 +151,6 @@ c.Selc(y, RegMod, RegZero),
c.Sub(lo, hi, y),
c.Addm(lo, lo, RegZero),
Return lo
- : forall ops : fancy_machine.instructions (2 * 128), expr base_type op Register (TZ -> TZ -> TW -> TW -> Tbase TW)
+ : forall ops : fancy_machine.instructions (2 * 128),
+ expr base_type op Register (Tbase TZ * Tbase TZ * Tbase TW * Tbase TW -> Tbase TW)
*)
diff --git a/src/Specific/GF25519Bounded.v b/src/Specific/GF25519Bounded.v
index 3f7087446..fafdc412b 100644
--- a/src/Specific/GF25519Bounded.v
+++ b/src/Specific/GF25519Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe25519.
+ generalize blem; generalize is_bounded_proj1_fe25519; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe25519W (opW (proj1_fe25519W f) (proj1_fe25519W g)) _);
+ refine (exist_fe25519W (opW (proj1_fe25519W f, proj1_fe25519W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe25519W (opW (proj1_fe25519W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe25519W) : fe25519W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe25519W) : fe25519W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe25519W) : fe25519W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe25519W * fe25519W) : fe25519W := Eval simpl in interp_radd f.
+Definition subW (f : fe25519W * fe25519W) : fe25519W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe25519W * fe25519W) : fe25519W := Eval simpl in interp_rmul f.
Definition oppW (f : fe25519W) : fe25519W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe25519W) : fe25519W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe25519W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe25519W) : fe25519W := Eval cbv beta delta [prefreezeW
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe25519W) chain := fold_chain_opt (proj1_fe25519W one) mulW_noinline chain [f].
+Definition powW (f : fe25519W) chain := fold_chain_opt (proj1_fe25519W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe25519W) : fe25519W
:= Eval cbv -[Let_In fe25519W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe25519WToZ length_fe25519].
cbv [postfreeze GF25519.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe25519WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF25519.eqb.
simpl @fe25519WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe25519WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF25519.sqrt] in GF25519.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe25519ZToW x) (chain GF25519.sqrt_ec) in
- GF25519.sqrt (fe25519WToZ powx) (fe25519WToZ (mulW_noinline powx powx)) x)
+ GF25519.sqrt (fe25519WToZ powx) (fe25519WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF25519.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe25519WToZ z with y => f end)
end;
change sqrt_m1 with (fe25519WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe25519WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe25519WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe25519WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe25519WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe25519WToZ x = fe25519WToZ x) by reflexivity.
+ unfold fe25519WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe25519WToZ (@?f x)] ]
=> let G' := context G[fe25519WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe25519W) : fe25519W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe25519) (chain : list (nat * nat)) : fe25519.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe25519) : fe25519.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe25519) : fe25519.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe25519
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe25519) chain : proj1_fe25519 (pow f chain) = GF25519.pow (proj1_fe25519 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe25519) : proj1_fe25519 (inv f) = GF25519.inv (proj1_fe25519 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe25519) : proj1_fe25519 (sqrt f) = GF25519sqrt (proj1_fe25519 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/Specific/GF25519BoundedAddCoordinates.v b/src/Specific/GF25519BoundedAddCoordinates.v
index cbc8666ea..2449c5388 100644
--- a/src/Specific/GF25519BoundedAddCoordinates.v
+++ b/src/Specific/GF25519BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519W) : Tuple.tuple fe25519W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519)
(proj1_fe25519 x7)
(proj1_fe25519 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/Specific/GF25519BoundedCommon.v b/src/Specific/GF25519BoundedCommon.v
index 683f5f47f..e9abe2f74 100644
--- a/src/Specific/GF25519BoundedCommon.v
+++ b/src/Specific/GF25519BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe25519W (Tuple.tuple fe25519W count_out) count_in)
(op : Tower.tower_nd GF25519.fe25519 (Tuple.tuple GF25519.fe25519 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe25519WToZ x) = true
- -> is_bounded (fe25519WToZ y) = true
- -> fe25519WToZ (irop x y) = op (fe25519WToZ x) (fe25519WToZ y)
- /\ is_bounded (fe25519WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe25519WToZ x) = true
- -> fe25519WToZ (irop x) = op (fe25519WToZ x)
- /\ is_bounded (fe25519WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe25519WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe25519WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe25519WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe25519WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe25519WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe25519WToZ x0) = true
- -> is_bounded (fe25519WToZ x1) = true
- -> is_bounded (fe25519WToZ x2) = true
- -> is_bounded (fe25519WToZ x3) = true
- -> is_bounded (fe25519WToZ x4) = true
- -> is_bounded (fe25519WToZ x5) = true
- -> is_bounded (fe25519WToZ x6) = true
- -> is_bounded (fe25519WToZ x7) = true
- -> is_bounded (fe25519WToZ x8) = true
- -> (Tuple.map (n:=k) fe25519WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe25519WToZ x0) (fe25519WToZ x1) (fe25519WToZ x2) (fe25519WToZ x3) (fe25519WToZ x4) (fe25519WToZ x5) (fe25519WToZ x6) (fe25519WToZ x7) (fe25519WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF25519.prefreeze.
+Notation prefreeze := GF25519.prefreeze.
diff --git a/src/Specific/GF25519BoundedExtendedAddCoordinates.v b/src/Specific/GF25519BoundedExtendedAddCoordinates.v
index cb42b9e7f..7b22bb5f4 100644
--- a/src/Specific/GF25519BoundedExtendedAddCoordinates.v
+++ b/src/Specific/GF25519BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.Specific.GF25519ExtendedAddCoordinates.
Require Import Crypto.Specific.GF25519BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF25519BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/Specific/GF25519Reflective.v b/src/Specific/GF25519Reflective.v
index e2b26016d..782b89563 100644
--- a/src/Specific/GF25519Reflective.v
+++ b/src/Specific/GF25519Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519W curry_unop_fe25519W curry_unop_wire_digitsW curry_9op_fe25519W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519W curry_unop_fe25519W curry_unop_wire_digitsW curry_9op_fe25519W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+Definition interp_radd : Specific.GF25519BoundedCommon.fe25519W * Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+Definition interp_rsub : Specific.GF25519BoundedCommon.fe25519W * Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+Definition interp_rmul : Specific.GF25519BoundedCommon.fe25519W * Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/Specific/GF25519Reflective/Common.v b/src/Specific/GF25519Reflective/Common.v
index 968f83be9..3e39809f5 100644
--- a/src/Specific/GF25519Reflective/Common.v
+++ b/src/Specific/GF25519Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe25519T] in
Syntax.tuple fe25519T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe25519T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe25519T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe25519T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
- := fun e => curry_binop_fe25519W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> Specific.GF25519BoundedCommon.fe25519W * Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.fe25519W
- := fun e => curry_unop_fe25519W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.word64
- := fun e => curry_unop_fe25519W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> Specific.GF25519BoundedCommon.fe25519W -> Specific.GF25519BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe25519W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> Specific.GF25519BoundedCommon.wire_digitsW -> Specific.GF25519BoundedCommon.fe25519W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
- -> Specific.GF25519BoundedCommon.fe25519W
+ -> Tuple.tuple Specific.GF25519BoundedCommon.fe25519W 9
-> Tuple.tuple Specific.GF25519BoundedCommon.fe25519W 4
- := fun e => curry_9op_fe25519W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF25519.fe25519 GF25519.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe25519 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe25519 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe25519 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe25519 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe25519 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe25519W) (H : is_bounded (fe25519WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe25519W * fe25519W)
(H : is_bounded (fe25519WToZ (fst x)) = true)
(H' : is_bounded (fe25519WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe25519W) (H : is_bounded (fe25519WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe25519W * fe25519W * fe25519W * fe25519W * fe25519W * fe25519W * fe25519W * fe25519W * fe25519W)
(H0 : is_bounded (fe25519WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe25519WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe25519W * fe25519W * fe25519W * fe25519W *
(H6 : is_bounded (fe25519WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe25519WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe25519WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe25519W curry_unop_fe25519W curry_unop_wire_digitsW curry_9op_fe25519W
curry_binop_fe25519 curry_unop_fe25519 curry_unop_wire_digits curry_9op_fe25519
uncurry_binop_fe25519W uncurry_unop_fe25519W uncurry_unop_wire_digitsW uncurry_9op_fe25519W
uncurry_binop_fe25519 uncurry_unop_fe25519 uncurry_unop_wire_digits uncurry_9op_fe25519
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe25519WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe25519WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe25519WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe25519WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe25519WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/Specific/GF25519Reflective/Common9_4Op.v b/src/Specific/GF25519Reflective/Common9_4Op.v
index 2d0f2d2cb..71f75530e 100644
--- a/src/Specific/GF25519Reflective/Common9_4Op.v
+++ b/src/Specific/GF25519Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/Specific/GF25519Reflective/CommonBinOp.v b/src/Specific/GF25519Reflective/CommonBinOp.v
index f3f8d4482..bb69bfcb1 100644
--- a/src/Specific/GF25519Reflective/CommonBinOp.v
+++ b/src/Specific/GF25519Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/Specific/GF25519Reflective/CommonUnOp.v b/src/Specific/GF25519Reflective/CommonUnOp.v
index 6d67170a4..2c997051a 100644
--- a/src/Specific/GF25519Reflective/CommonUnOp.v
+++ b/src/Specific/GF25519Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe25519WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/Specific/GF25519Reflective/CommonUnOpFEToWire.v b/src/Specific/GF25519Reflective/CommonUnOpFEToWire.v
index fc3fa5a63..9230e440b 100644
--- a/src/Specific/GF25519Reflective/CommonUnOpFEToWire.v
+++ b/src/Specific/GF25519Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe25519WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/Specific/GF25519Reflective/CommonUnOpFEToZ.v b/src/Specific/GF25519Reflective/CommonUnOpFEToZ.v
index f112184e9..e8ae58b9a 100644
--- a/src/Specific/GF25519Reflective/CommonUnOpFEToZ.v
+++ b/src/Specific/GF25519Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe25519WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/Specific/GF25519Reflective/CommonUnOpWireToFE.v b/src/Specific/GF25519Reflective/CommonUnOpWireToFE.v
index 0ba44ecc9..3a861d03b 100644
--- a/src/Specific/GF25519Reflective/CommonUnOpWireToFE.v
+++ b/src/Specific/GF25519Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.Specific.GF25519BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/Specific/GF25519Reflective/Reified/AddCoordinates.v b/src/Specific/GF25519Reflective/Reified/AddCoordinates.v
index e14c6c239..4fc2d2c0a 100644
--- a/src/Specific/GF25519Reflective/Reified/AddCoordinates.v
+++ b/src/Specific/GF25519Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.Specific.GF25519Reflective.Common.
Require Import Crypto.Specific.GF25519Reflective.Reified.Add.
Require Import Crypto.Specific.GF25519Reflective.Reified.Sub.
Require Import Crypto.Specific.GF25519Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe25519)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519.fe25519 -> GF25519.fe25519 -> GF25519.fe25519)
- (x' y' : GF25519.fe25519)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519.fe25519] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe25519 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF25519.fe25519].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/Specific/GF25519Reflective/Reified/LadderStep.v b/src/Specific/GF25519Reflective/Reified/LadderStep.v
index bab53cc52..1964fcaec 100644
--- a/src/Specific/GF25519Reflective/Reified/LadderStep.v
+++ b/src/Specific/GF25519Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.Specific.GF25519Reflective.Common.
Require Import Crypto.Specific.GF25519Reflective.Reified.Add.
Require Import Crypto.Specific.GF25519Reflective.Reified.Sub.
Require Import Crypto.Specific.GF25519Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe25519)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519.fe25519 -> GF25519.fe25519 -> GF25519.fe25519)
- (x' y' : GF25519.fe25519)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519.fe25519] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe25519 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF25519.fe25519].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/Specific/GF25519Reflective/Reified/PreFreeze.v b/src/Specific/GF25519Reflective/Reified/PreFreeze.v
index 9322185e3..6b3bce924 100644
--- a/src/Specific/GF25519Reflective/Reified/PreFreeze.v
+++ b/src/Specific/GF25519Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.Specific.GF25519Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF25519.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/Specific/GF25519Reflective/Reified/rebuild-reified.py b/src/Specific/GF25519Reflective/Reified/rebuild-reified.py
index 8d434276e..f9348d0cc 100755
--- a/src/Specific/GF25519Reflective/Reified/rebuild-reified.py
+++ b/src/Specific/GF25519Reflective/Reified/rebuild-reified.py
@@ -8,24 +8,23 @@ for name, opkind in ([(name, 'BinOp') for name in ('Add', 'Carry_Add', 'Sub', 'C
lopkind = opkind.replace('UnOp', 'unop').replace('BinOp', 'binop')
uopkind = opkind.replace('_', '')
extra = ''
- if name in ('Carry_Add', 'Carry_Sub', 'Mul', 'Carry_Opp', 'Pack', 'Unpack', 'Ge_Modulus', 'PreFreeze'):
- extra = r"""Local Obligation Tactic := intros; vm_compute; constructor.
-Program Definition r%(lname)sW_correct_and_bounded
- := Expr%(uopkind)s_correct_and_bounded
- r%(lname)sW %(lname)s r%(lname)sZ_sig r%(lname)sW_correct_and_bounded_gen
- _ _.
+ #if name in ('Carry_Add', 'Carry_Sub', 'Mul', 'Carry_Opp', 'Pack', 'Unpack', 'Ge_Modulus', 'PreFreeze'):
+ extra = r"""Local Obligation Tactic := intros; vm_compute; constructor.
+Program Definition r%(lname)sZ_correct_and_bounded
+ := rexpr_correct_and_bounded r%(lname)sZ r%(lname)sZ_Wf Expr%(uopkind)s_bounds.
""" % locals()
with open(name.replace('_', '') + '.v', 'w') as f:
- f.write(r"""Require Import Crypto.Specific.GF25519Reflective.Common%(uopkind)s.
+ f.write(r"""Require Import Crypto.Specific.GF25519Reflective.Common.
Definition r%(lname)sZ_sig : rexpr_%(lopkind)s_sig %(lname)s. Proof. reify_sig. Defined.
-Definition r%(lname)sW := Eval vm_compute in rword_of_Z r%(lname)sZ_sig.
-Lemma r%(lname)sW_correct_and_bounded_gen : correct_and_bounded_genT r%(lname)sW r%(lname)sZ_sig.
-Proof. rexpr_correct. Qed.
-Definition r%(lname)s_output_bounds := Eval vm_compute in compute_bounds r%(lname)sW Expr%(uopkind)s_bounds.
+Definition r%(lname)sZ : Syntax.Expr _ _ _ := Eval vm_compute in proj1_sig r%(lname)sZ_sig.
+Definition r%(lname)sW : Syntax.Expr _ _ _ := Eval vm_compute in rexpr_select_word_sizes r%(lname)sZ Expr%(uopkind)s_bounds.
+Definition r%(lname)sZ_Wf : rexpr_wfT r%(lname)sZ. Proof. prove_rexpr_wfT. Qed.
+Definition r%(lname)s_output_bounds
+ := Eval vm_compute in compute_bounds r%(lname)sZ Expr%(uopkind)s_bounds.
%(extra)s
Local Open Scope string_scope.
-Compute ("%(name)s", compute_bounds_for_display r%(lname)sW Expr%(uopkind)s_bounds).
-Compute ("%(name)s overflows? ", sanity_compute r%(lname)sW Expr%(uopkind)s_bounds).
-Compute ("%(name)s overflows (error if it does)? ", sanity_check r%(lname)sW Expr%(uopkind)s_bounds).
+Compute ("%(name)s", compute_bounds_for_display r%(lname)sZ Expr%(uopkind)s_bounds).
+Compute ("%(name)s overflows? ", sanity_compute r%(lname)sZ Expr%(uopkind)s_bounds).
+Compute ("%(name)s overflows (error if it does)? ", sanity_check r%(lname)sZ Expr%(uopkind)s_bounds).
""" % locals())
diff --git a/src/Specific/GF25519ReflectiveAddCoordinates.v b/src/Specific/GF25519ReflectiveAddCoordinates.v
index c4e88f2a7..c40c093ed 100644
--- a/src/Specific/GF25519ReflectiveAddCoordinates.v
+++ b/src/Specific/GF25519ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : Specific.GF25519BoundedCommon.fe25519W
-> Specific.GF25519BoundedCommon.fe25519W
-> Specific.GF25519BoundedCommon.fe25519W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF2213_32Bounded.v b/src/SpecificGen/GF2213_32Bounded.v
index c98f234a0..c207dc557 100644
--- a/src/SpecificGen/GF2213_32Bounded.v
+++ b/src/SpecificGen/GF2213_32Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe2213_32.
+ generalize blem; generalize is_bounded_proj1_fe2213_32; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe2213_32W (opW (proj1_fe2213_32W f) (proj1_fe2213_32W g)) _);
+ refine (exist_fe2213_32W (opW (proj1_fe2213_32W f, proj1_fe2213_32W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe2213_32W (opW (proj1_fe2213_32W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe2213_32W) : fe2213_32W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe2213_32W) : fe2213_32W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe2213_32W) : fe2213_32W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe2213_32W * fe2213_32W) : fe2213_32W := Eval simpl in interp_radd f.
+Definition subW (f : fe2213_32W * fe2213_32W) : fe2213_32W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe2213_32W * fe2213_32W) : fe2213_32W := Eval simpl in interp_rmul f.
Definition oppW (f : fe2213_32W) : fe2213_32W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe2213_32W) : fe2213_32W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe2213_32W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe2213_32W) : fe2213_32W := Eval cbv beta delta [prefree
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe2213_32W) chain := fold_chain_opt (proj1_fe2213_32W one) mulW_noinline chain [f].
+Definition powW (f : fe2213_32W) chain := fold_chain_opt (proj1_fe2213_32W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe2213_32W) : fe2213_32W
:= Eval cbv -[Let_In fe2213_32W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe2213_32WToZ length_fe2213_32].
cbv [postfreeze GF2213_32.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe2213_32WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF2213_32.eqb.
simpl @fe2213_32WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe2213_32WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe2213_32WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF2213_32.sqrt] in GF2213_32.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe2213_32ZToW x) (chain GF2213_32.sqrt_ec) in
- GF2213_32.sqrt (fe2213_32WToZ powx) (fe2213_32WToZ (mulW_noinline powx powx)) x)
+ GF2213_32.sqrt (fe2213_32WToZ powx) (fe2213_32WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF2213_32.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe2213_32WToZ z with y => f end)
end;
change sqrt_m1 with (fe2213_32WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe2213_32WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe2213_32WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe2213_32WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe2213_32WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe2213_32WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe2213_32WToZ x = fe2213_32WToZ x) by reflexivity.
+ unfold fe2213_32WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe2213_32WToZ (@?f x)] ]
=> let G' := context G[fe2213_32WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe2213_32W) : fe2213_32W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe2213_32) (chain : list (nat * nat)) : fe2213_32.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe2213_32) : fe2213_32.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe2213_32) : fe2213_32.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe2213_32
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe2213_32) chain : proj1_fe2213_32 (pow f chain) = GF2213_32.pow (proj1_fe2213_32 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe2213_32) : proj1_fe2213_32 (inv f) = GF2213_32.inv (proj1_fe2213_32 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe2213_32) : proj1_fe2213_32 (sqrt f) = GF2213_32sqrt (proj1_fe2213_32 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF2213_32BoundedAddCoordinates.v b/src/SpecificGen/GF2213_32BoundedAddCoordinates.v
index 6079aadc9..86d5b1db7 100644
--- a/src/SpecificGen/GF2213_32BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF2213_32BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe2213_32W) : Tuple.tuple fe2213_32W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe2213_32)
(proj1_fe2213_32 x7)
(proj1_fe2213_32 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF2213_32BoundedCommon.v b/src/SpecificGen/GF2213_32BoundedCommon.v
index f9b215ac9..c1b109cc2 100644
--- a/src/SpecificGen/GF2213_32BoundedCommon.v
+++ b/src/SpecificGen/GF2213_32BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe2213_32WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe2213_32 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe2213_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe2213_32WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe2213_32 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe2213_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe2213_32WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe2213_32W (Tuple.tuple fe2213_32W count_out) count_in)
(op : Tower.tower_nd GF2213_32.fe2213_32 (Tuple.tuple GF2213_32.fe2213_32 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe2213_32WToZ x) = true
- -> is_bounded (fe2213_32WToZ y) = true
- -> fe2213_32WToZ (irop x y) = op (fe2213_32WToZ x) (fe2213_32WToZ y)
- /\ is_bounded (fe2213_32WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe2213_32WToZ x) = true
- -> fe2213_32WToZ (irop x) = op (fe2213_32WToZ x)
- /\ is_bounded (fe2213_32WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe2213_32WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe2213_32WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe2213_32WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe2213_32WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe2213_32WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe2213_32WToZ x0) = true
- -> is_bounded (fe2213_32WToZ x1) = true
- -> is_bounded (fe2213_32WToZ x2) = true
- -> is_bounded (fe2213_32WToZ x3) = true
- -> is_bounded (fe2213_32WToZ x4) = true
- -> is_bounded (fe2213_32WToZ x5) = true
- -> is_bounded (fe2213_32WToZ x6) = true
- -> is_bounded (fe2213_32WToZ x7) = true
- -> is_bounded (fe2213_32WToZ x8) = true
- -> (Tuple.map (n:=k) fe2213_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe2213_32WToZ x0) (fe2213_32WToZ x1) (fe2213_32WToZ x2) (fe2213_32WToZ x3) (fe2213_32WToZ x4) (fe2213_32WToZ x5) (fe2213_32WToZ x6) (fe2213_32WToZ x7) (fe2213_32WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe2213_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF2213_32.prefreeze.
+Notation prefreeze := GF2213_32.prefreeze.
diff --git a/src/SpecificGen/GF2213_32BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF2213_32BoundedExtendedAddCoordinates.v
index 58c297578..9ef98db72 100644
--- a/src/SpecificGen/GF2213_32BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF2213_32BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF2213_32ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF2213_32BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF2213_32BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF2213_32Reflective.v b/src/SpecificGen/GF2213_32Reflective.v
index 078dc2c4a..e871b3a91 100644
--- a/src/SpecificGen/GF2213_32Reflective.v
+++ b/src/SpecificGen/GF2213_32Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe2213_32W curry_unop_fe2213_32W curry_unop_wire_digitsW curry_9op_fe2213_32W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe2213_32W curry_unop_fe2213_32W curry_unop_wire_digitsW curry_9op_fe2213_32W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
+Definition interp_radd : SpecificGen.GF2213_32BoundedCommon.fe2213_32W * SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
+Definition interp_rsub : SpecificGen.GF2213_32BoundedCommon.fe2213_32W * SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
+Definition interp_rmul : SpecificGen.GF2213_32BoundedCommon.fe2213_32W * SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF2213_32Reflective/Common.v b/src/SpecificGen/GF2213_32Reflective/Common.v
index bcaa5d064..f1f4921b4 100644
--- a/src/SpecificGen/GF2213_32Reflective/Common.v
+++ b/src/SpecificGen/GF2213_32Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe2213_32T] in
Syntax.tuple fe2213_32T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe2213_32T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe2213_32T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe2213_32T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe2213_32 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe2213_32 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- := fun e => curry_binop_fe2213_32W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W * SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- := fun e => curry_unop_fe2213_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.word64
- := fun e => curry_unop_fe2213_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W -> SpecificGen.GF2213_32BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe2213_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF2213_32BoundedCommon.wire_digitsW -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
- -> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
+ -> Tuple.tuple SpecificGen.GF2213_32BoundedCommon.fe2213_32W 9
-> Tuple.tuple SpecificGen.GF2213_32BoundedCommon.fe2213_32W 4
- := fun e => curry_9op_fe2213_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF2213_32.fe2213_32 GF2213_32.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe2213_32 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe2213_32 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe2213_32 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe2213_32 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe2213_32 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe2213_32W) (H : is_bounded (fe2213_32WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe2213_32W * fe2213_32W)
(H : is_bounded (fe2213_32WToZ (fst x)) = true)
(H' : is_bounded (fe2213_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe2213_32W) (H : is_bounded (fe2213_32WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W * fe2213_32W)
(H0 : is_bounded (fe2213_32WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe2213_32WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe2213_32W * fe2213_32W * fe2213_32W * fe221
(H6 : is_bounded (fe2213_32WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe2213_32WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe2213_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe2213_32 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe2213_32 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe2213_32W curry_unop_fe2213_32W curry_unop_wire_digitsW curry_9op_fe2213_32W
curry_binop_fe2213_32 curry_unop_fe2213_32 curry_unop_wire_digits curry_9op_fe2213_32
uncurry_binop_fe2213_32W uncurry_unop_fe2213_32W uncurry_unop_wire_digitsW uncurry_9op_fe2213_32W
uncurry_binop_fe2213_32 uncurry_unop_fe2213_32 uncurry_unop_wire_digits uncurry_9op_fe2213_32
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe2213_32WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe2213_32WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe2213_32WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe2213_32WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe2213_32WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF2213_32Reflective/Common9_4Op.v b/src/SpecificGen/GF2213_32Reflective/Common9_4Op.v
index fb8b27f18..587eff7a7 100644
--- a/src/SpecificGen/GF2213_32Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF2213_32Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/SpecificGen/GF2213_32Reflective/CommonBinOp.v b/src/SpecificGen/GF2213_32Reflective/CommonBinOp.v
index 8ad7f623c..3d38818f4 100644
--- a/src/SpecificGen/GF2213_32Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF2213_32Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF2213_32Reflective/CommonUnOp.v b/src/SpecificGen/GF2213_32Reflective/CommonUnOp.v
index 40b39edf4..8f8035405 100644
--- a/src/SpecificGen/GF2213_32Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF2213_32Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe2213_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToWire.v
index 60c0726dc..76f1635df 100644
--- a/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe2213_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToZ.v
index bc5a6e265..95dbd10cd 100644
--- a/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF2213_32Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe2213_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2213_32Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF2213_32Reflective/CommonUnOpWireToFE.v
index e4f57d7bb..45094aa32 100644
--- a/src/SpecificGen/GF2213_32Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF2213_32Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2213_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2213_32Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF2213_32Reflective/Reified/AddCoordinates.v
index 84ac36861..0230b3427 100644
--- a/src/SpecificGen/GF2213_32Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF2213_32Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF2213_32Reflective.Common.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe2213_32)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF2213_32.fe2213_32 -> GF2213_32.fe2213_32 -> GF2213_32.fe2213_32)
- (x' y' : GF2213_32.fe2213_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe2213_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe2213_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF2213_32.fe2213_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe2213_32 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe2213_32 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe2213_32 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF2213_32.fe2213_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF2213_32Reflective/Reified/LadderStep.v b/src/SpecificGen/GF2213_32Reflective/Reified/LadderStep.v
index f4fa2daff..7136ce80a 100644
--- a/src/SpecificGen/GF2213_32Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF2213_32Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF2213_32Reflective.Common.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF2213_32Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe2213_32)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF2213_32.fe2213_32 -> GF2213_32.fe2213_32 -> GF2213_32.fe2213_32)
- (x' y' : GF2213_32.fe2213_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe2213_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe2213_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF2213_32.fe2213_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe2213_32 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe2213_32 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe2213_32 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF2213_32.fe2213_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF2213_32Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF2213_32Reflective/Reified/PreFreeze.v
index 60ab908b0..359a9c432 100644
--- a/src/SpecificGen/GF2213_32Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF2213_32Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF2213_32Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF2213_32.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF2213_32ReflectiveAddCoordinates.v b/src/SpecificGen/GF2213_32ReflectiveAddCoordinates.v
index aaf0c2833..dbe640f39 100644
--- a/src/SpecificGen/GF2213_32ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF2213_32ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF2213_32BoundedCommon.fe2213_32W
-> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
-> SpecificGen.GF2213_32BoundedCommon.fe2213_32W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF2519_32Bounded.v b/src/SpecificGen/GF2519_32Bounded.v
index 9cb723690..83dcec8a4 100644
--- a/src/SpecificGen/GF2519_32Bounded.v
+++ b/src/SpecificGen/GF2519_32Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe2519_32.
+ generalize blem; generalize is_bounded_proj1_fe2519_32; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe2519_32W (opW (proj1_fe2519_32W f) (proj1_fe2519_32W g)) _);
+ refine (exist_fe2519_32W (opW (proj1_fe2519_32W f, proj1_fe2519_32W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe2519_32W (opW (proj1_fe2519_32W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe2519_32W) : fe2519_32W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe2519_32W) : fe2519_32W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe2519_32W) : fe2519_32W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe2519_32W * fe2519_32W) : fe2519_32W := Eval simpl in interp_radd f.
+Definition subW (f : fe2519_32W * fe2519_32W) : fe2519_32W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe2519_32W * fe2519_32W) : fe2519_32W := Eval simpl in interp_rmul f.
Definition oppW (f : fe2519_32W) : fe2519_32W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe2519_32W) : fe2519_32W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe2519_32W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe2519_32W) : fe2519_32W := Eval cbv beta delta [prefree
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe2519_32W) chain := fold_chain_opt (proj1_fe2519_32W one) mulW_noinline chain [f].
+Definition powW (f : fe2519_32W) chain := fold_chain_opt (proj1_fe2519_32W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe2519_32W) : fe2519_32W
:= Eval cbv -[Let_In fe2519_32W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe2519_32WToZ length_fe2519_32].
cbv [postfreeze GF2519_32.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe2519_32WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF2519_32.eqb.
simpl @fe2519_32WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe2519_32WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe2519_32WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF2519_32.sqrt] in GF2519_32.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe2519_32ZToW x) (chain GF2519_32.sqrt_ec) in
- GF2519_32.sqrt (fe2519_32WToZ powx) (fe2519_32WToZ (mulW_noinline powx powx)) x)
+ GF2519_32.sqrt (fe2519_32WToZ powx) (fe2519_32WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF2519_32.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe2519_32WToZ z with y => f end)
end;
change sqrt_m1 with (fe2519_32WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe2519_32WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe2519_32WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe2519_32WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe2519_32WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe2519_32WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe2519_32WToZ x = fe2519_32WToZ x) by reflexivity.
+ unfold fe2519_32WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe2519_32WToZ (@?f x)] ]
=> let G' := context G[fe2519_32WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe2519_32W) : fe2519_32W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe2519_32) (chain : list (nat * nat)) : fe2519_32.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe2519_32) : fe2519_32.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe2519_32) : fe2519_32.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe2519_32
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe2519_32) chain : proj1_fe2519_32 (pow f chain) = GF2519_32.pow (proj1_fe2519_32 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe2519_32) : proj1_fe2519_32 (inv f) = GF2519_32.inv (proj1_fe2519_32 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe2519_32) : proj1_fe2519_32 (sqrt f) = GF2519_32sqrt (proj1_fe2519_32 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF2519_32BoundedAddCoordinates.v b/src/SpecificGen/GF2519_32BoundedAddCoordinates.v
index 68b97f000..6ff1a8198 100644
--- a/src/SpecificGen/GF2519_32BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF2519_32BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe2519_32W) : Tuple.tuple fe2519_32W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe2519_32)
(proj1_fe2519_32 x7)
(proj1_fe2519_32 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF2519_32BoundedCommon.v b/src/SpecificGen/GF2519_32BoundedCommon.v
index f6bf77cb0..b37b6bc4e 100644
--- a/src/SpecificGen/GF2519_32BoundedCommon.v
+++ b/src/SpecificGen/GF2519_32BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe2519_32WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe2519_32 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe2519_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe2519_32WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe2519_32 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe2519_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe2519_32WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe2519_32W (Tuple.tuple fe2519_32W count_out) count_in)
(op : Tower.tower_nd GF2519_32.fe2519_32 (Tuple.tuple GF2519_32.fe2519_32 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe2519_32WToZ x) = true
- -> is_bounded (fe2519_32WToZ y) = true
- -> fe2519_32WToZ (irop x y) = op (fe2519_32WToZ x) (fe2519_32WToZ y)
- /\ is_bounded (fe2519_32WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe2519_32WToZ x) = true
- -> fe2519_32WToZ (irop x) = op (fe2519_32WToZ x)
- /\ is_bounded (fe2519_32WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe2519_32WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe2519_32WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe2519_32WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe2519_32WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe2519_32WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe2519_32WToZ x0) = true
- -> is_bounded (fe2519_32WToZ x1) = true
- -> is_bounded (fe2519_32WToZ x2) = true
- -> is_bounded (fe2519_32WToZ x3) = true
- -> is_bounded (fe2519_32WToZ x4) = true
- -> is_bounded (fe2519_32WToZ x5) = true
- -> is_bounded (fe2519_32WToZ x6) = true
- -> is_bounded (fe2519_32WToZ x7) = true
- -> is_bounded (fe2519_32WToZ x8) = true
- -> (Tuple.map (n:=k) fe2519_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe2519_32WToZ x0) (fe2519_32WToZ x1) (fe2519_32WToZ x2) (fe2519_32WToZ x3) (fe2519_32WToZ x4) (fe2519_32WToZ x5) (fe2519_32WToZ x6) (fe2519_32WToZ x7) (fe2519_32WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe2519_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF2519_32.prefreeze.
+Notation prefreeze := GF2519_32.prefreeze.
diff --git a/src/SpecificGen/GF2519_32BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF2519_32BoundedExtendedAddCoordinates.v
index 309a62324..eb6602760 100644
--- a/src/SpecificGen/GF2519_32BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF2519_32BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF2519_32ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF2519_32BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF2519_32BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF2519_32Reflective.v b/src/SpecificGen/GF2519_32Reflective.v
index 6b912c7ea..6c5759e0d 100644
--- a/src/SpecificGen/GF2519_32Reflective.v
+++ b/src/SpecificGen/GF2519_32Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe2519_32W curry_unop_fe2519_32W curry_unop_wire_digitsW curry_9op_fe2519_32W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe2519_32W curry_unop_fe2519_32W curry_unop_wire_digitsW curry_9op_fe2519_32W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
+Definition interp_radd : SpecificGen.GF2519_32BoundedCommon.fe2519_32W * SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
+Definition interp_rsub : SpecificGen.GF2519_32BoundedCommon.fe2519_32W * SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
+Definition interp_rmul : SpecificGen.GF2519_32BoundedCommon.fe2519_32W * SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF2519_32Reflective/Common.v b/src/SpecificGen/GF2519_32Reflective/Common.v
index db99360d7..ea27f9a6b 100644
--- a/src/SpecificGen/GF2519_32Reflective/Common.v
+++ b/src/SpecificGen/GF2519_32Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe2519_32T] in
Syntax.tuple fe2519_32T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe2519_32T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe2519_32T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe2519_32T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe2519_32 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe2519_32 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- := fun e => curry_binop_fe2519_32W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W * SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- := fun e => curry_unop_fe2519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.word64
- := fun e => curry_unop_fe2519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W -> SpecificGen.GF2519_32BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe2519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF2519_32BoundedCommon.wire_digitsW -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
- -> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
+ -> Tuple.tuple SpecificGen.GF2519_32BoundedCommon.fe2519_32W 9
-> Tuple.tuple SpecificGen.GF2519_32BoundedCommon.fe2519_32W 4
- := fun e => curry_9op_fe2519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF2519_32.fe2519_32 GF2519_32.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe2519_32 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe2519_32 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe2519_32 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe2519_32 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe2519_32 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe2519_32W) (H : is_bounded (fe2519_32WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe2519_32W * fe2519_32W)
(H : is_bounded (fe2519_32WToZ (fst x)) = true)
(H' : is_bounded (fe2519_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe2519_32W) (H : is_bounded (fe2519_32WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W * fe2519_32W)
(H0 : is_bounded (fe2519_32WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe2519_32WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe2519_32W * fe2519_32W * fe2519_32W * fe251
(H6 : is_bounded (fe2519_32WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe2519_32WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe2519_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe2519_32 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe2519_32 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe2519_32W curry_unop_fe2519_32W curry_unop_wire_digitsW curry_9op_fe2519_32W
curry_binop_fe2519_32 curry_unop_fe2519_32 curry_unop_wire_digits curry_9op_fe2519_32
uncurry_binop_fe2519_32W uncurry_unop_fe2519_32W uncurry_unop_wire_digitsW uncurry_9op_fe2519_32W
uncurry_binop_fe2519_32 uncurry_unop_fe2519_32 uncurry_unop_wire_digits uncurry_9op_fe2519_32
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe2519_32WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe2519_32WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe2519_32WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe2519_32WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe2519_32WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF2519_32Reflective/Common9_4Op.v b/src/SpecificGen/GF2519_32Reflective/Common9_4Op.v
index 990ad0e53..90befd75b 100644
--- a/src/SpecificGen/GF2519_32Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF2519_32Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/SpecificGen/GF2519_32Reflective/CommonBinOp.v b/src/SpecificGen/GF2519_32Reflective/CommonBinOp.v
index c0c390d0b..bf8795d45 100644
--- a/src/SpecificGen/GF2519_32Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF2519_32Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF2519_32Reflective/CommonUnOp.v b/src/SpecificGen/GF2519_32Reflective/CommonUnOp.v
index b2117295a..418dfd5e5 100644
--- a/src/SpecificGen/GF2519_32Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF2519_32Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe2519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToWire.v
index 1b20ac0f5..6668a3b64 100644
--- a/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe2519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToZ.v
index dc49c8ec8..bdf2a49c7 100644
--- a/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF2519_32Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe2519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2519_32Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF2519_32Reflective/CommonUnOpWireToFE.v
index b500e4cb0..c2f260694 100644
--- a/src/SpecificGen/GF2519_32Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF2519_32Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF2519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF2519_32Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF2519_32Reflective/Reified/AddCoordinates.v
index 6c0ee65e7..4411362c0 100644
--- a/src/SpecificGen/GF2519_32Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF2519_32Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF2519_32Reflective.Common.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe2519_32)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF2519_32.fe2519_32 -> GF2519_32.fe2519_32 -> GF2519_32.fe2519_32)
- (x' y' : GF2519_32.fe2519_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe2519_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe2519_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF2519_32.fe2519_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe2519_32 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe2519_32 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe2519_32 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF2519_32.fe2519_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF2519_32Reflective/Reified/LadderStep.v b/src/SpecificGen/GF2519_32Reflective/Reified/LadderStep.v
index b29f1822b..1a4204457 100644
--- a/src/SpecificGen/GF2519_32Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF2519_32Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF2519_32Reflective.Common.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF2519_32Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe2519_32)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF2519_32.fe2519_32 -> GF2519_32.fe2519_32 -> GF2519_32.fe2519_32)
- (x' y' : GF2519_32.fe2519_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe2519_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe2519_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF2519_32.fe2519_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe2519_32 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe2519_32 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe2519_32 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF2519_32.fe2519_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF2519_32Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF2519_32Reflective/Reified/PreFreeze.v
index dc9e2dcef..fd509d77c 100644
--- a/src/SpecificGen/GF2519_32Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF2519_32Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF2519_32Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF2519_32.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF2519_32ReflectiveAddCoordinates.v b/src/SpecificGen/GF2519_32ReflectiveAddCoordinates.v
index 3ceccc8dd..4010eac57 100644
--- a/src/SpecificGen/GF2519_32ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF2519_32ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF2519_32BoundedCommon.fe2519_32W
-> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
-> SpecificGen.GF2519_32BoundedCommon.fe2519_32W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF25519_32Bounded.v b/src/SpecificGen/GF25519_32Bounded.v
index 03a1bb125..025950bee 100644
--- a/src/SpecificGen/GF25519_32Bounded.v
+++ b/src/SpecificGen/GF25519_32Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe25519_32.
+ generalize blem; generalize is_bounded_proj1_fe25519_32; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe25519_32W (opW (proj1_fe25519_32W f) (proj1_fe25519_32W g)) _);
+ refine (exist_fe25519_32W (opW (proj1_fe25519_32W f, proj1_fe25519_32W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe25519_32W (opW (proj1_fe25519_32W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe25519_32W) : fe25519_32W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe25519_32W) : fe25519_32W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe25519_32W) : fe25519_32W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe25519_32W * fe25519_32W) : fe25519_32W := Eval simpl in interp_radd f.
+Definition subW (f : fe25519_32W * fe25519_32W) : fe25519_32W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe25519_32W * fe25519_32W) : fe25519_32W := Eval simpl in interp_rmul f.
Definition oppW (f : fe25519_32W) : fe25519_32W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe25519_32W) : fe25519_32W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe25519_32W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe25519_32W) : fe25519_32W := Eval cbv beta delta [prefr
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe25519_32W) chain := fold_chain_opt (proj1_fe25519_32W one) mulW_noinline chain [f].
+Definition powW (f : fe25519_32W) chain := fold_chain_opt (proj1_fe25519_32W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe25519_32W) : fe25519_32W
:= Eval cbv -[Let_In fe25519_32W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe25519_32WToZ length_fe25519_32].
cbv [postfreeze GF25519_32.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe25519_32WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF25519_32.eqb.
simpl @fe25519_32WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519_32WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe25519_32WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF25519_32.sqrt] in GF25519_32.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe25519_32ZToW x) (chain GF25519_32.sqrt_ec) in
- GF25519_32.sqrt (fe25519_32WToZ powx) (fe25519_32WToZ (mulW_noinline powx powx)) x)
+ GF25519_32.sqrt (fe25519_32WToZ powx) (fe25519_32WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF25519_32.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe25519_32WToZ z with y => f end)
end;
change sqrt_m1 with (fe25519_32WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe25519_32WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe25519_32WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe25519_32WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519_32WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe25519_32WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe25519_32WToZ x = fe25519_32WToZ x) by reflexivity.
+ unfold fe25519_32WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe25519_32WToZ (@?f x)] ]
=> let G' := context G[fe25519_32WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe25519_32W) : fe25519_32W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe25519_32) (chain : list (nat * nat)) : fe25519_32.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe25519_32) : fe25519_32.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe25519_32) : fe25519_32.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe25519_32
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe25519_32) chain : proj1_fe25519_32 (pow f chain) = GF25519_32.pow (proj1_fe25519_32 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe25519_32) : proj1_fe25519_32 (inv f) = GF25519_32.inv (proj1_fe25519_32 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe25519_32) : proj1_fe25519_32 (sqrt f) = GF25519_32sqrt (proj1_fe25519_32 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF25519_32BoundedAddCoordinates.v b/src/SpecificGen/GF25519_32BoundedAddCoordinates.v
index 5a1fd12b3..6e5bdae4f 100644
--- a/src/SpecificGen/GF25519_32BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF25519_32BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519_32W) : Tuple.tuple fe25519_32W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519_32)
(proj1_fe25519_32 x7)
(proj1_fe25519_32 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF25519_32BoundedCommon.v b/src/SpecificGen/GF25519_32BoundedCommon.v
index bf76e028b..f21a391b8 100644
--- a/src/SpecificGen/GF25519_32BoundedCommon.v
+++ b/src/SpecificGen/GF25519_32BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519_32WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519_32 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519_32WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519_32 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519_32WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe25519_32W (Tuple.tuple fe25519_32W count_out) count_in)
(op : Tower.tower_nd GF25519_32.fe25519_32 (Tuple.tuple GF25519_32.fe25519_32 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe25519_32WToZ x) = true
- -> is_bounded (fe25519_32WToZ y) = true
- -> fe25519_32WToZ (irop x y) = op (fe25519_32WToZ x) (fe25519_32WToZ y)
- /\ is_bounded (fe25519_32WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe25519_32WToZ x) = true
- -> fe25519_32WToZ (irop x) = op (fe25519_32WToZ x)
- /\ is_bounded (fe25519_32WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe25519_32WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe25519_32WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe25519_32WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe25519_32WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe25519_32WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe25519_32WToZ x0) = true
- -> is_bounded (fe25519_32WToZ x1) = true
- -> is_bounded (fe25519_32WToZ x2) = true
- -> is_bounded (fe25519_32WToZ x3) = true
- -> is_bounded (fe25519_32WToZ x4) = true
- -> is_bounded (fe25519_32WToZ x5) = true
- -> is_bounded (fe25519_32WToZ x6) = true
- -> is_bounded (fe25519_32WToZ x7) = true
- -> is_bounded (fe25519_32WToZ x8) = true
- -> (Tuple.map (n:=k) fe25519_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe25519_32WToZ x0) (fe25519_32WToZ x1) (fe25519_32WToZ x2) (fe25519_32WToZ x3) (fe25519_32WToZ x4) (fe25519_32WToZ x5) (fe25519_32WToZ x6) (fe25519_32WToZ x7) (fe25519_32WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF25519_32.prefreeze.
+Notation prefreeze := GF25519_32.prefreeze.
diff --git a/src/SpecificGen/GF25519_32BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF25519_32BoundedExtendedAddCoordinates.v
index c23bcea4a..4d28f5376 100644
--- a/src/SpecificGen/GF25519_32BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF25519_32BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF25519_32ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF25519_32BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF25519_32BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF25519_32Reflective.v b/src/SpecificGen/GF25519_32Reflective.v
index cfa76bf01..6e3f169ea 100644
--- a/src/SpecificGen/GF25519_32Reflective.v
+++ b/src/SpecificGen/GF25519_32Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519_32W curry_unop_fe25519_32W curry_unop_wire_digitsW curry_9op_fe25519_32W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519_32W curry_unop_fe25519_32W curry_unop_wire_digitsW curry_9op_fe25519_32W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
+Definition interp_radd : SpecificGen.GF25519_32BoundedCommon.fe25519_32W * SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
+Definition interp_rsub : SpecificGen.GF25519_32BoundedCommon.fe25519_32W * SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
+Definition interp_rmul : SpecificGen.GF25519_32BoundedCommon.fe25519_32W * SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF25519_32Reflective/Common.v b/src/SpecificGen/GF25519_32Reflective/Common.v
index 3d3686a54..29d653cd6 100644
--- a/src/SpecificGen/GF25519_32Reflective/Common.v
+++ b/src/SpecificGen/GF25519_32Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe25519_32T] in
Syntax.tuple fe25519_32T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe25519_32T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe25519_32T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe25519_32T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519_32 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519_32 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- := fun e => curry_binop_fe25519_32W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W * SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- := fun e => curry_unop_fe25519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.word64
- := fun e => curry_unop_fe25519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W -> SpecificGen.GF25519_32BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe25519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF25519_32BoundedCommon.wire_digitsW -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
- -> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
+ -> Tuple.tuple SpecificGen.GF25519_32BoundedCommon.fe25519_32W 9
-> Tuple.tuple SpecificGen.GF25519_32BoundedCommon.fe25519_32W 4
- := fun e => curry_9op_fe25519_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF25519_32.fe25519_32 GF25519_32.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe25519_32 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe25519_32 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe25519_32 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe25519_32 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe25519_32 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe25519_32W) (H : is_bounded (fe25519_32WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe25519_32W * fe25519_32W)
(H : is_bounded (fe25519_32WToZ (fst x)) = true)
(H' : is_bounded (fe25519_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe25519_32W) (H : is_bounded (fe25519_32WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W * fe25519_32W)
(H0 : is_bounded (fe25519_32WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe25519_32WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe25519_32W * fe25519_32W * fe25519_32W * fe
(H6 : is_bounded (fe25519_32WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe25519_32WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe25519_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519_32 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519_32 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe25519_32W curry_unop_fe25519_32W curry_unop_wire_digitsW curry_9op_fe25519_32W
curry_binop_fe25519_32 curry_unop_fe25519_32 curry_unop_wire_digits curry_9op_fe25519_32
uncurry_binop_fe25519_32W uncurry_unop_fe25519_32W uncurry_unop_wire_digitsW uncurry_9op_fe25519_32W
uncurry_binop_fe25519_32 uncurry_unop_fe25519_32 uncurry_unop_wire_digits uncurry_9op_fe25519_32
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe25519_32WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe25519_32WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe25519_32WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe25519_32WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe25519_32WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF25519_32Reflective/Common9_4Op.v b/src/SpecificGen/GF25519_32Reflective/Common9_4Op.v
index 286724558..e9b0209db 100644
--- a/src/SpecificGen/GF25519_32Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF25519_32Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/SpecificGen/GF25519_32Reflective/CommonBinOp.v b/src/SpecificGen/GF25519_32Reflective/CommonBinOp.v
index 6a8a54fdd..48fc98b9d 100644
--- a/src/SpecificGen/GF25519_32Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF25519_32Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF25519_32Reflective/CommonUnOp.v b/src/SpecificGen/GF25519_32Reflective/CommonUnOp.v
index 8df0c1685..8bfdba221 100644
--- a/src/SpecificGen/GF25519_32Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF25519_32Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe25519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToWire.v
index d97e1e8c9..1bc40e3a9 100644
--- a/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe25519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToZ.v
index 1a6f994e5..9d9e24690 100644
--- a/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF25519_32Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe25519_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_32Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF25519_32Reflective/CommonUnOpWireToFE.v
index 62572dc0c..3d6ba7d3b 100644
--- a/src/SpecificGen/GF25519_32Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF25519_32Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_32Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF25519_32Reflective/Reified/AddCoordinates.v
index e013a84e5..5d0b9deb7 100644
--- a/src/SpecificGen/GF25519_32Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF25519_32Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF25519_32Reflective.Common.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe25519_32)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519_32.fe25519_32 -> GF25519_32.fe25519_32 -> GF25519_32.fe25519_32)
- (x' y' : GF25519_32.fe25519_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519_32.fe25519_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519_32 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe25519_32 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519_32 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF25519_32.fe25519_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF25519_32Reflective/Reified/LadderStep.v b/src/SpecificGen/GF25519_32Reflective/Reified/LadderStep.v
index ae71337fd..36919539d 100644
--- a/src/SpecificGen/GF25519_32Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF25519_32Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF25519_32Reflective.Common.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF25519_32Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe25519_32)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519_32.fe25519_32 -> GF25519_32.fe25519_32 -> GF25519_32.fe25519_32)
- (x' y' : GF25519_32.fe25519_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519_32.fe25519_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519_32 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe25519_32 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519_32 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF25519_32.fe25519_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF25519_32Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF25519_32Reflective/Reified/PreFreeze.v
index 1ba921294..8cdacd63f 100644
--- a/src/SpecificGen/GF25519_32Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF25519_32Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF25519_32Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF25519_32.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF25519_32ReflectiveAddCoordinates.v b/src/SpecificGen/GF25519_32ReflectiveAddCoordinates.v
index 1392cb2f6..c2a9414f4 100644
--- a/src/SpecificGen/GF25519_32ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF25519_32ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF25519_32BoundedCommon.fe25519_32W
-> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
-> SpecificGen.GF25519_32BoundedCommon.fe25519_32W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF25519_64Bounded.v b/src/SpecificGen/GF25519_64Bounded.v
index 8100182ed..e602af2e5 100644
--- a/src/SpecificGen/GF25519_64Bounded.v
+++ b/src/SpecificGen/GF25519_64Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe25519_64.
+ generalize blem; generalize is_bounded_proj1_fe25519_64; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe25519_64W (opW (proj1_fe25519_64W f) (proj1_fe25519_64W g)) _);
+ refine (exist_fe25519_64W (opW (proj1_fe25519_64W f, proj1_fe25519_64W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe25519_64W (opW (proj1_fe25519_64W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord128.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe25519_64W) : fe25519_64W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe25519_64W) : fe25519_64W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe25519_64W) : fe25519_64W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe25519_64W * fe25519_64W) : fe25519_64W := Eval simpl in interp_radd f.
+Definition subW (f : fe25519_64W * fe25519_64W) : fe25519_64W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe25519_64W * fe25519_64W) : fe25519_64W := Eval simpl in interp_rmul f.
Definition oppW (f : fe25519_64W) : fe25519_64W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe25519_64W) : fe25519_64W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe25519_64W) : word128 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe25519_64W) : fe25519_64W := Eval cbv beta delta [prefr
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe25519_64W) chain := fold_chain_opt (proj1_fe25519_64W one) mulW_noinline chain [f].
+Definition powW (f : fe25519_64W) chain := fold_chain_opt (proj1_fe25519_64W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe25519_64W) : fe25519_64W
:= Eval cbv -[Let_In fe25519_64W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe25519_64WToZ length_fe25519_64].
cbv [postfreeze GF25519_64.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe25519_64WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF25519_64.eqb.
simpl @fe25519_64WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519_64WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe25519_64WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF25519_64.sqrt] in GF25519_64.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe25519_64ZToW x) (chain GF25519_64.sqrt_ec) in
- GF25519_64.sqrt (fe25519_64WToZ powx) (fe25519_64WToZ (mulW_noinline powx powx)) x)
+ GF25519_64.sqrt (fe25519_64WToZ powx) (fe25519_64WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF25519_64.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe25519_64WToZ z with y => f end)
end;
change sqrt_m1 with (fe25519_64WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe25519_64WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe25519_64WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe25519_64WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe25519_64WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe25519_64WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe25519_64WToZ x = fe25519_64WToZ x) by reflexivity.
+ unfold fe25519_64WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe25519_64WToZ (@?f x)] ]
=> let G' := context G[fe25519_64WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe25519_64W) : fe25519_64W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe25519_64) (chain : list (nat * nat)) : fe25519_64.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe25519_64) : fe25519_64.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe25519_64) : fe25519_64.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe25519_64
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe25519_64) chain : proj1_fe25519_64 (pow f chain) = GF25519_64.pow (proj1_fe25519_64 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe25519_64) : proj1_fe25519_64 (inv f) = GF25519_64.inv (proj1_fe25519_64 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe25519_64) : proj1_fe25519_64 (sqrt f) = GF25519_64sqrt (proj1_fe25519_64 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF25519_64BoundedAddCoordinates.v b/src/SpecificGen/GF25519_64BoundedAddCoordinates.v
index a1ba335c8..711af3078 100644
--- a/src/SpecificGen/GF25519_64BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF25519_64BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord128.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519_64W) : Tuple.tuple fe25519_64W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe25519_64)
(proj1_fe25519_64 x7)
(proj1_fe25519_64 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF25519_64BoundedCommon.v b/src/SpecificGen/GF25519_64BoundedCommon.v
index b4c8e47ca..1c91f4d88 100644
--- a/src/SpecificGen/GF25519_64BoundedCommon.v
+++ b/src/SpecificGen/GF25519_64BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519_64WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519_64 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519_64 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe25519_64WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe25519_64 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe25519_64 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519_64WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe25519_64W (Tuple.tuple fe25519_64W count_out) count_in)
(op : Tower.tower_nd GF25519_64.fe25519_64 (Tuple.tuple GF25519_64.fe25519_64 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe25519_64WToZ x) = true
- -> is_bounded (fe25519_64WToZ y) = true
- -> fe25519_64WToZ (irop x y) = op (fe25519_64WToZ x) (fe25519_64WToZ y)
- /\ is_bounded (fe25519_64WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe25519_64WToZ x) = true
- -> fe25519_64WToZ (irop x) = op (fe25519_64WToZ x)
- /\ is_bounded (fe25519_64WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe25519_64WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe25519_64WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe25519_64WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe25519_64WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe25519_64WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe25519_64WToZ x0) = true
- -> is_bounded (fe25519_64WToZ x1) = true
- -> is_bounded (fe25519_64WToZ x2) = true
- -> is_bounded (fe25519_64WToZ x3) = true
- -> is_bounded (fe25519_64WToZ x4) = true
- -> is_bounded (fe25519_64WToZ x5) = true
- -> is_bounded (fe25519_64WToZ x6) = true
- -> is_bounded (fe25519_64WToZ x7) = true
- -> is_bounded (fe25519_64WToZ x8) = true
- -> (Tuple.map (n:=k) fe25519_64WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe25519_64WToZ x0) (fe25519_64WToZ x1) (fe25519_64WToZ x2) (fe25519_64WToZ x3) (fe25519_64WToZ x4) (fe25519_64WToZ x5) (fe25519_64WToZ x6) (fe25519_64WToZ x7) (fe25519_64WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe25519_64WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF25519_64.prefreeze.
+Notation prefreeze := GF25519_64.prefreeze.
diff --git a/src/SpecificGen/GF25519_64BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF25519_64BoundedExtendedAddCoordinates.v
index d5e92dfac..b7d07d9c2 100644
--- a/src/SpecificGen/GF25519_64BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF25519_64BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF25519_64ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF25519_64BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF25519_64BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF25519_64Reflective.v b/src/SpecificGen/GF25519_64Reflective.v
index b92c70202..142c1e6ae 100644
--- a/src/SpecificGen/GF25519_64Reflective.v
+++ b/src/SpecificGen/GF25519_64Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519_64W curry_unop_fe25519_64W curry_unop_wire_digitsW curry_9op_fe25519_64W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe25519_64W curry_unop_fe25519_64W curry_unop_wire_digitsW curry_9op_fe25519_64W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
+Definition interp_radd : SpecificGen.GF25519_64BoundedCommon.fe25519_64W * SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
+Definition interp_rsub : SpecificGen.GF25519_64BoundedCommon.fe25519_64W * SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
+Definition interp_rmul : SpecificGen.GF25519_64BoundedCommon.fe25519_64W * SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF25519_64Reflective/Common.v b/src/SpecificGen/GF25519_64Reflective/Common.v
index b592451eb..edb0c5fb1 100644
--- a/src/SpecificGen/GF25519_64Reflective/Common.v
+++ b/src/SpecificGen/GF25519_64Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Crypto.Reflection.Z.Interpretations128.Relations.
Require Import Crypto.Reflection.Z.Interpretations128.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe25519_64T] in
Syntax.tuple fe25519_64T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe25519_64T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe25519_64T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe25519_64T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519_64 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe25519_64 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- := fun e => curry_binop_fe25519_64W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W * SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- := fun e => curry_unop_fe25519_64W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.word128
- := fun e => curry_unop_fe25519_64W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W -> SpecificGen.GF25519_64BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe25519_64W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF25519_64BoundedCommon.wire_digitsW -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
- -> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
+ -> Tuple.tuple SpecificGen.GF25519_64BoundedCommon.fe25519_64W 9
-> Tuple.tuple SpecificGen.GF25519_64BoundedCommon.fe25519_64W 4
- := fun e => curry_9op_fe25519_64W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF25519_64.fe25519_64 GF25519_64.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe25519_64 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe25519_64 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe25519_64 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe25519_64 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe25519_64 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word128)
+ (H : is_bounded_gen (Tuple.map (fun v : word128 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word128 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word128 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word128 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word128 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe25519_64W) (H : is_bounded (fe25519_64WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word128 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word128 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word128 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word128 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe25519_64W * fe25519_64W)
(H : is_bounded (fe25519_64WToZ (fst x)) = true)
(H' : is_bounded (fe25519_64WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe25519_64W) (H : is_bounded (fe25519_64WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W * fe25519_64W)
(H0 : is_bounded (fe25519_64WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe25519_64WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe25519_64W * fe25519_64W * fe25519_64W * fe
(H6 : is_bounded (fe25519_64WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe25519_64WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe25519_64WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519_64 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe25519_64 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe25519_64W curry_unop_fe25519_64W curry_unop_wire_digitsW curry_9op_fe25519_64W
curry_binop_fe25519_64 curry_unop_fe25519_64 curry_unop_wire_digits curry_9op_fe25519_64
uncurry_binop_fe25519_64W uncurry_unop_fe25519_64W uncurry_unop_wire_digitsW uncurry_9op_fe25519_64W
uncurry_binop_fe25519_64 uncurry_unop_fe25519_64 uncurry_unop_wire_digits uncurry_9op_fe25519_64
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe25519_64WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word128 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe25519_64WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe25519_64WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe25519_64WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word128ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word128ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe25519_64WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize128.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF25519_64Reflective/Common9_4Op.v b/src/SpecificGen/GF25519_64Reflective/Common9_4Op.v
index 9435884a4..a1443cefa 100644
--- a/src/SpecificGen/GF25519_64Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF25519_64Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.128s) (successful) *)*)
diff --git a/src/SpecificGen/GF25519_64Reflective/CommonBinOp.v b/src/SpecificGen/GF25519_64Reflective/CommonBinOp.v
index 1d174ae2b..9f26d8521 100644
--- a/src/SpecificGen/GF25519_64Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF25519_64Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF25519_64Reflective/CommonUnOp.v b/src/SpecificGen/GF25519_64Reflective/CommonUnOp.v
index a5b57d394..aa26e495a 100644
--- a/src/SpecificGen/GF25519_64Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF25519_64Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe25519_64WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToWire.v
index cdda3c4eb..f1f30d64c 100644
--- a/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe25519_64WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToZ.v
index d082f70b0..48a5b9610 100644
--- a/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF25519_64Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe25519_64WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_64Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF25519_64Reflective/CommonUnOpWireToFE.v
index 327a6b825..3e7112480 100644
--- a/src/SpecificGen/GF25519_64Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF25519_64Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF25519_64BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF25519_64Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF25519_64Reflective/Reified/AddCoordinates.v
index 0f41ed239..3fe4fbeef 100644
--- a/src/SpecificGen/GF25519_64Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF25519_64Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Crypto.Reflection.Z.Interpretations128.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF25519_64Reflective.Common.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe25519_64)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519_64.fe25519_64 -> GF25519_64.fe25519_64 -> GF25519_64.fe25519_64)
- (x' y' : GF25519_64.fe25519_64)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519_64 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519_64 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519_64.fe25519_64] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519_64 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe25519_64 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519_64 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF25519_64.fe25519_64].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF25519_64Reflective/Reified/LadderStep.v b/src/SpecificGen/GF25519_64Reflective/Reified/LadderStep.v
index 66d998d08..f3d2204b0 100644
--- a/src/SpecificGen/GF25519_64Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF25519_64Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations128.
Require Crypto.Reflection.Z.Interpretations128.Relations.
Require Import Crypto.Reflection.Z.Interpretations128.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF25519_64Reflective.Common.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF25519_64Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe25519_64)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF25519_64.fe25519_64 -> GF25519_64.fe25519_64 -> GF25519_64.fe25519_64)
- (x' y' : GF25519_64.fe25519_64)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe25519_64 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe25519_64 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF25519_64.fe25519_64] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe25519_64 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe25519_64 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe25519_64 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF25519_64.fe25519_64].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF25519_64Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF25519_64Reflective/Reified/PreFreeze.v
index 457ffa715..610060dfc 100644
--- a/src/SpecificGen/GF25519_64Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF25519_64Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF25519_64Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF25519_64.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF25519_64ReflectiveAddCoordinates.v b/src/SpecificGen/GF25519_64ReflectiveAddCoordinates.v
index 2527f2c90..d4a05dec1 100644
--- a/src/SpecificGen/GF25519_64ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF25519_64ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word128ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF25519_64BoundedCommon.fe25519_64W
-> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
-> SpecificGen.GF25519_64BoundedCommon.fe25519_64W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF41417_32Bounded.v b/src/SpecificGen/GF41417_32Bounded.v
index 17e8f70e7..4748ee6ff 100644
--- a/src/SpecificGen/GF41417_32Bounded.v
+++ b/src/SpecificGen/GF41417_32Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe41417_32.
+ generalize blem; generalize is_bounded_proj1_fe41417_32; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe41417_32W (opW (proj1_fe41417_32W f) (proj1_fe41417_32W g)) _);
+ refine (exist_fe41417_32W (opW (proj1_fe41417_32W f, proj1_fe41417_32W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe41417_32W (opW (proj1_fe41417_32W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe41417_32W) : fe41417_32W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe41417_32W) : fe41417_32W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe41417_32W) : fe41417_32W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe41417_32W * fe41417_32W) : fe41417_32W := Eval simpl in interp_radd f.
+Definition subW (f : fe41417_32W * fe41417_32W) : fe41417_32W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe41417_32W * fe41417_32W) : fe41417_32W := Eval simpl in interp_rmul f.
Definition oppW (f : fe41417_32W) : fe41417_32W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe41417_32W) : fe41417_32W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe41417_32W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe41417_32W) : fe41417_32W := Eval cbv beta delta [prefr
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe41417_32W) chain := fold_chain_opt (proj1_fe41417_32W one) mulW_noinline chain [f].
+Definition powW (f : fe41417_32W) chain := fold_chain_opt (proj1_fe41417_32W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe41417_32W) : fe41417_32W
:= Eval cbv -[Let_In fe41417_32W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe41417_32WToZ length_fe41417_32].
cbv [postfreeze GF41417_32.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe41417_32WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF41417_32.eqb.
simpl @fe41417_32WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe41417_32WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe41417_32WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF41417_32.sqrt] in GF41417_32.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe41417_32ZToW x) (chain GF41417_32.sqrt_ec) in
- GF41417_32.sqrt (fe41417_32WToZ powx) (fe41417_32WToZ (mulW_noinline powx powx)) x)
+ GF41417_32.sqrt (fe41417_32WToZ powx) (fe41417_32WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF41417_32.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe41417_32WToZ z with y => f end)
end;
change sqrt_m1 with (fe41417_32WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe41417_32WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe41417_32WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe41417_32WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe41417_32WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe41417_32WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe41417_32WToZ x = fe41417_32WToZ x) by reflexivity.
+ unfold fe41417_32WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe41417_32WToZ (@?f x)] ]
=> let G' := context G[fe41417_32WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe41417_32W) : fe41417_32W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe41417_32) (chain : list (nat * nat)) : fe41417_32.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe41417_32) : fe41417_32.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe41417_32) : fe41417_32.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe41417_32
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe41417_32) chain : proj1_fe41417_32 (pow f chain) = GF41417_32.pow (proj1_fe41417_32 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe41417_32) : proj1_fe41417_32 (inv f) = GF41417_32.inv (proj1_fe41417_32 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe41417_32) : proj1_fe41417_32 (sqrt f) = GF41417_32sqrt (proj1_fe41417_32 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF41417_32BoundedAddCoordinates.v b/src/SpecificGen/GF41417_32BoundedAddCoordinates.v
index e7d5842ce..b4f6ba5a8 100644
--- a/src/SpecificGen/GF41417_32BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF41417_32BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe41417_32W) : Tuple.tuple fe41417_32W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe41417_32)
(proj1_fe41417_32 x7)
(proj1_fe41417_32 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF41417_32BoundedCommon.v b/src/SpecificGen/GF41417_32BoundedCommon.v
index 2bf69d425..6705d924b 100644
--- a/src/SpecificGen/GF41417_32BoundedCommon.v
+++ b/src/SpecificGen/GF41417_32BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe41417_32WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe41417_32 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe41417_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe41417_32WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe41417_32 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe41417_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe41417_32WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe41417_32W (Tuple.tuple fe41417_32W count_out) count_in)
(op : Tower.tower_nd GF41417_32.fe41417_32 (Tuple.tuple GF41417_32.fe41417_32 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe41417_32WToZ x) = true
- -> is_bounded (fe41417_32WToZ y) = true
- -> fe41417_32WToZ (irop x y) = op (fe41417_32WToZ x) (fe41417_32WToZ y)
- /\ is_bounded (fe41417_32WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe41417_32WToZ x) = true
- -> fe41417_32WToZ (irop x) = op (fe41417_32WToZ x)
- /\ is_bounded (fe41417_32WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe41417_32WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe41417_32WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe41417_32WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe41417_32WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe41417_32WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe41417_32WToZ x0) = true
- -> is_bounded (fe41417_32WToZ x1) = true
- -> is_bounded (fe41417_32WToZ x2) = true
- -> is_bounded (fe41417_32WToZ x3) = true
- -> is_bounded (fe41417_32WToZ x4) = true
- -> is_bounded (fe41417_32WToZ x5) = true
- -> is_bounded (fe41417_32WToZ x6) = true
- -> is_bounded (fe41417_32WToZ x7) = true
- -> is_bounded (fe41417_32WToZ x8) = true
- -> (Tuple.map (n:=k) fe41417_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe41417_32WToZ x0) (fe41417_32WToZ x1) (fe41417_32WToZ x2) (fe41417_32WToZ x3) (fe41417_32WToZ x4) (fe41417_32WToZ x5) (fe41417_32WToZ x6) (fe41417_32WToZ x7) (fe41417_32WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe41417_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF41417_32.prefreeze.
+Notation prefreeze := GF41417_32.prefreeze.
diff --git a/src/SpecificGen/GF41417_32BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF41417_32BoundedExtendedAddCoordinates.v
index dc99e0b11..94bc097cf 100644
--- a/src/SpecificGen/GF41417_32BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF41417_32BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF41417_32ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF41417_32BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF41417_32BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF41417_32Reflective.v b/src/SpecificGen/GF41417_32Reflective.v
index 4b9b012b1..404111062 100644
--- a/src/SpecificGen/GF41417_32Reflective.v
+++ b/src/SpecificGen/GF41417_32Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe41417_32W curry_unop_fe41417_32W curry_unop_wire_digitsW curry_9op_fe41417_32W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe41417_32W curry_unop_fe41417_32W curry_unop_wire_digitsW curry_9op_fe41417_32W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
+Definition interp_radd : SpecificGen.GF41417_32BoundedCommon.fe41417_32W * SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
+Definition interp_rsub : SpecificGen.GF41417_32BoundedCommon.fe41417_32W * SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
+Definition interp_rmul : SpecificGen.GF41417_32BoundedCommon.fe41417_32W * SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF41417_32Reflective/Common.v b/src/SpecificGen/GF41417_32Reflective/Common.v
index d537c6018..75ce71bca 100644
--- a/src/SpecificGen/GF41417_32Reflective/Common.v
+++ b/src/SpecificGen/GF41417_32Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe41417_32T] in
Syntax.tuple fe41417_32T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe41417_32T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe41417_32T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe41417_32T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe41417_32 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe41417_32 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- := fun e => curry_binop_fe41417_32W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W * SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- := fun e => curry_unop_fe41417_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.word64
- := fun e => curry_unop_fe41417_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W -> SpecificGen.GF41417_32BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe41417_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF41417_32BoundedCommon.wire_digitsW -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
- -> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
+ -> Tuple.tuple SpecificGen.GF41417_32BoundedCommon.fe41417_32W 9
-> Tuple.tuple SpecificGen.GF41417_32BoundedCommon.fe41417_32W 4
- := fun e => curry_9op_fe41417_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF41417_32.fe41417_32 GF41417_32.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe41417_32 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe41417_32 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe41417_32 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe41417_32 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe41417_32 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe41417_32W) (H : is_bounded (fe41417_32WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe41417_32W * fe41417_32W)
(H : is_bounded (fe41417_32WToZ (fst x)) = true)
(H' : is_bounded (fe41417_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe41417_32W) (H : is_bounded (fe41417_32WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W * fe41417_32W)
(H0 : is_bounded (fe41417_32WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe41417_32WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe41417_32W * fe41417_32W * fe41417_32W * fe
(H6 : is_bounded (fe41417_32WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe41417_32WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe41417_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe41417_32 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe41417_32 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe41417_32W curry_unop_fe41417_32W curry_unop_wire_digitsW curry_9op_fe41417_32W
curry_binop_fe41417_32 curry_unop_fe41417_32 curry_unop_wire_digits curry_9op_fe41417_32
uncurry_binop_fe41417_32W uncurry_unop_fe41417_32W uncurry_unop_wire_digitsW uncurry_9op_fe41417_32W
uncurry_binop_fe41417_32 uncurry_unop_fe41417_32 uncurry_unop_wire_digits uncurry_9op_fe41417_32
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe41417_32WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe41417_32WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe41417_32WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe41417_32WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe41417_32WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF41417_32Reflective/Common9_4Op.v b/src/SpecificGen/GF41417_32Reflective/Common9_4Op.v
index 4590d5871..0e7336d2e 100644
--- a/src/SpecificGen/GF41417_32Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF41417_32Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/SpecificGen/GF41417_32Reflective/CommonBinOp.v b/src/SpecificGen/GF41417_32Reflective/CommonBinOp.v
index d55d12f1d..9cf8f3bf6 100644
--- a/src/SpecificGen/GF41417_32Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF41417_32Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF41417_32Reflective/CommonUnOp.v b/src/SpecificGen/GF41417_32Reflective/CommonUnOp.v
index 92a928bfc..5c369d730 100644
--- a/src/SpecificGen/GF41417_32Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF41417_32Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe41417_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToWire.v
index 4c8923dd9..312d4439e 100644
--- a/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe41417_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToZ.v
index 748e2fd10..76fcf7e88 100644
--- a/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF41417_32Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe41417_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF41417_32Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF41417_32Reflective/CommonUnOpWireToFE.v
index d70798964..553a9583d 100644
--- a/src/SpecificGen/GF41417_32Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF41417_32Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF41417_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF41417_32Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF41417_32Reflective/Reified/AddCoordinates.v
index 0a8480432..362d69158 100644
--- a/src/SpecificGen/GF41417_32Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF41417_32Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF41417_32Reflective.Common.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe41417_32)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF41417_32.fe41417_32 -> GF41417_32.fe41417_32 -> GF41417_32.fe41417_32)
- (x' y' : GF41417_32.fe41417_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe41417_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe41417_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF41417_32.fe41417_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe41417_32 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe41417_32 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe41417_32 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF41417_32.fe41417_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF41417_32Reflective/Reified/LadderStep.v b/src/SpecificGen/GF41417_32Reflective/Reified/LadderStep.v
index 0d1cd59cb..80e929103 100644
--- a/src/SpecificGen/GF41417_32Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF41417_32Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF41417_32Reflective.Common.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF41417_32Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe41417_32)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF41417_32.fe41417_32 -> GF41417_32.fe41417_32 -> GF41417_32.fe41417_32)
- (x' y' : GF41417_32.fe41417_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe41417_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe41417_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF41417_32.fe41417_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe41417_32 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe41417_32 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe41417_32 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF41417_32.fe41417_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF41417_32Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF41417_32Reflective/Reified/PreFreeze.v
index 889c6ca49..ede666d32 100644
--- a/src/SpecificGen/GF41417_32Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF41417_32Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF41417_32Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF41417_32.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF41417_32ReflectiveAddCoordinates.v b/src/SpecificGen/GF41417_32ReflectiveAddCoordinates.v
index c08f28dfe..54c260408 100644
--- a/src/SpecificGen/GF41417_32ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF41417_32ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF41417_32BoundedCommon.fe41417_32W
-> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
-> SpecificGen.GF41417_32BoundedCommon.fe41417_32W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)
diff --git a/src/SpecificGen/GF5211_32Bounded.v b/src/SpecificGen/GF5211_32Bounded.v
index 5bd8b85c2..02ea3614f 100644
--- a/src/SpecificGen/GF5211_32Bounded.v
+++ b/src/SpecificGen/GF5211_32Bounded.v
@@ -25,13 +25,23 @@ Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.
Local Open Scope Z.
+Local Ltac cbv_tuple_map :=
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'].
+
+Local Ltac post_bounded_t :=
+ (* much pain and hackery to work around [Defined] taking forever *)
+ cbv_tuple_map;
+ let blem' := fresh "blem'" in
+ let is_bounded_lem := fresh "is_bounded_lem" in
+ intros is_bounded_lem blem';
+ apply blem'; repeat apply conj; apply is_bounded_lem.
Local Ltac bounded_t opW blem :=
- apply blem; apply is_bounded_proj1_fe5211_32.
+ generalize blem; generalize is_bounded_proj1_fe5211_32; post_bounded_t.
Local Ltac bounded_wire_digits_t opW blem :=
- apply blem; apply is_bounded_proj1_wire_digits.
+ generalize blem; generalize is_bounded_proj1_wire_digits; post_bounded_t.
Local Ltac define_binop f g opW blem :=
- refine (exist_fe5211_32W (opW (proj1_fe5211_32W f) (proj1_fe5211_32W g)) _);
+ refine (exist_fe5211_32W (opW (proj1_fe5211_32W f, proj1_fe5211_32W g)) _);
abstract bounded_t opW blem.
Local Ltac define_unop f opW blem :=
refine (exist_fe5211_32W (opW (proj1_fe5211_32W f)) _);
@@ -47,17 +57,17 @@ Local Ltac define_unop_WireToFE f opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd / _ _.
-Local Arguments interp_rsub / _ _.
-Local Arguments interp_rmul / _ _.
+Local Arguments interp_radd / _.
+Local Arguments interp_rsub / _.
+Local Arguments interp_rmul / _.
Local Arguments interp_ropp / _.
Local Arguments interp_rprefreeze / _.
Local Arguments interp_rge_modulus / _.
Local Arguments interp_rpack / _.
Local Arguments interp_runpack / _.
-Definition addW (f g : fe5211_32W) : fe5211_32W := Eval simpl in interp_radd f g.
-Definition subW (f g : fe5211_32W) : fe5211_32W := Eval simpl in interp_rsub f g.
-Definition mulW (f g : fe5211_32W) : fe5211_32W := Eval simpl in interp_rmul f g.
+Definition addW (f : fe5211_32W * fe5211_32W) : fe5211_32W := Eval simpl in interp_radd f.
+Definition subW (f : fe5211_32W * fe5211_32W) : fe5211_32W := Eval simpl in interp_rsub f.
+Definition mulW (f : fe5211_32W * fe5211_32W) : fe5211_32W := Eval simpl in interp_rmul f.
Definition oppW (f : fe5211_32W) : fe5211_32W := Eval simpl in interp_ropp f.
Definition prefreezeW (f : fe5211_32W) : fe5211_32W := Eval simpl in interp_rprefreeze f.
Definition ge_modulusW (f : fe5211_32W) : word64 := Eval simpl in interp_rge_modulus f.
@@ -86,7 +96,7 @@ Definition freezeW (f : fe5211_32W) : fe5211_32W := Eval cbv beta delta [prefree
Local Transparent Let_In.
(* Wrapper to allow extracted code to not unfold [mulW] *)
Definition mulW_noinline := mulW.
-Definition powW (f : fe5211_32W) chain := fold_chain_opt (proj1_fe5211_32W one) mulW_noinline chain [f].
+Definition powW (f : fe5211_32W) chain := fold_chain_opt (proj1_fe5211_32W one) (fun f g => mulW_noinline (f, g)) chain [f].
Definition invW (f : fe5211_32W) : fe5211_32W
:= Eval cbv -[Let_In fe5211_32W mulW_noinline] in powW f (chain inv_ec).
@@ -95,11 +105,11 @@ Local Ltac port_correct_and_bounded pre_rewrite opW interp_rop rop_cb :=
rewrite pre_rewrite;
intros; apply rop_cb; assumption.
-Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW carry_add.
+Lemma addW_correct_and_bounded : ibinop_correct_and_bounded addW (Curry.curry2 carry_add).
Proof. port_correct_and_bounded interp_radd_correct addW interp_radd radd_correct_and_bounded. Qed.
-Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW carry_sub.
+Lemma subW_correct_and_bounded : ibinop_correct_and_bounded subW (Curry.curry2 carry_sub).
Proof. port_correct_and_bounded interp_rsub_correct subW interp_rsub rsub_correct_and_bounded. Qed.
-Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW mul.
+Lemma mulW_correct_and_bounded : ibinop_correct_and_bounded mulW (Curry.curry2 mul).
Proof. port_correct_and_bounded interp_rmul_correct mulW interp_rmul rmul_correct_and_bounded. Qed.
Lemma oppW_correct_and_bounded : iunop_correct_and_bounded oppW carry_opp.
Proof. port_correct_and_bounded interp_ropp_correct oppW interp_ropp ropp_correct_and_bounded. Qed.
@@ -142,6 +152,7 @@ Proof.
cbv [modulusW Tuple.map].
cbv [on_tuple List.map to_list to_list' from_list from_list'
+ HList.hlistP HList.hlistP'
Tuple.map2 on_tuple2 ListUtil.map2 fe5211_32WToZ length_fe5211_32].
cbv [postfreeze GF5211_32.postfreeze].
cbv [Let_In].
@@ -203,7 +214,8 @@ Proof.
change (freezeW f) with (postfreezeW (prefreezeW f)).
destruct (prefreezeW_correct_and_bounded f H) as [H0 H1].
destruct (postfreezeW_correct_and_bounded _ H1) as [H0' H1'].
- rewrite H1', H0', H0; split; reflexivity.
+ split; [ | assumption ].
+ rewrite H0', H0; reflexivity.
Qed.
Lemma powW_correct_and_bounded chain : iunop_correct_and_bounded (fun x => powW x chain) (fun x => pow x chain).
@@ -212,9 +224,11 @@ Proof.
intro x; intros; apply (fold_chain_opt_gen fe5211_32WToZ is_bounded [x]).
{ reflexivity. }
{ reflexivity. }
- { intros; progress rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption.
- apply mulW_correct_and_bounded; assumption. }
- { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded _ _ X Y)) by assumption; reflexivity. }
+ { intros; pose proof (fun k0 k1 X Y => proj1 (mulW_correct_and_bounded (k0, k1) (conj X Y))) as H'.
+ cbv [Curry.curry2 Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list'] in H'.
+ rewrite <- H' by assumption.
+ apply mulW_correct_and_bounded; split; assumption. }
+ { intros; rewrite (fun X Y => proj1 (mulW_correct_and_bounded (_, _) (conj X Y))) by assumption; reflexivity. }
{ intros [|?]; autorewrite with simpl_nth_default;
(assumption || reflexivity). }
Qed.
@@ -269,8 +283,10 @@ Proof.
unfold GF5211_32.eqb.
simpl @fe5211_32WToZ in *; cbv beta iota.
intros.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe5211_32WToZ] in *.
rewrite <- frf, <- frg by assumption.
- rewrite <- fieldwisebW_correct.
+ etransitivity; [ eapply fieldwisebW_correct | ].
+ cbv [fe5211_32WToZ].
reflexivity.
Defined.
@@ -297,7 +313,7 @@ Proof.
lazymatch (eval cbv delta [GF5211_32.sqrt] in GF5211_32.sqrt) with
| (fun powf powf_squared f => dlet a := powf in _)
=> exact (dlet powx := powW (fe5211_32ZToW x) (chain GF5211_32.sqrt_ec) in
- GF5211_32.sqrt (fe5211_32WToZ powx) (fe5211_32WToZ (mulW_noinline powx powx)) x)
+ GF5211_32.sqrt (fe5211_32WToZ powx) (fe5211_32WToZ (mulW_noinline (powx, powx))) x)
| (fun f => pow f _)
=> exact (GF5211_32.sqrt x)
end.
@@ -324,21 +340,41 @@ Proof.
=> is_var z; change (x = match fe5211_32WToZ z with y => f end)
end;
change sqrt_m1 with (fe5211_32WToZ sqrt_m1W);
- rewrite <- (fun X Y => proj1 (mulW_correct_and_bounded sqrt_m1W a X Y)), <- eqbW_correct, (pull_bool_if fe5211_32WToZ)
- by repeat match goal with
- | _ => progress subst
- | [ |- is_bounded (fe5211_32WToZ ?op) = true ]
- => lazymatch op with
- | mulW _ _ => apply mulW_correct_and_bounded
- | mulW_noinline _ _ => apply mulW_correct_and_bounded
- | powW _ _ => apply powW_correct_and_bounded
- | sqrt_m1W => vm_compute; reflexivity
- | _ => assumption
- end
- end;
- subst_evars; reflexivity
+ pose proof (fun X Y => proj1 (mulW_correct_and_bounded (sqrt_m1W, a) (conj X Y))) as correctness;
+ let cbv_in_all _ := (cbv [fe5211_32WToZ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' fe5211_32WToZ Curry.curry2 HList.hlistP HList.hlistP'] in *; idtac) in
+ cbv_in_all ();
+ let solver _ := (repeat match goal with
+ | _ => progress subst
+ | _ => progress unfold fst, snd
+ | _ => progress cbv_in_all ()
+ | [ |- ?x /\ ?x ] => cut x; [ intro; split; assumption | ]
+ | [ |- is_bounded ?op = true ]
+ => let H := fresh in
+ lazymatch op with
+ | context[mulW (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[mulW_noinline (_, _)] => pose proof mulW_correct_and_bounded as H
+ | context[powW _ _] => pose proof powW_correct_and_bounded as H
+ | context[sqrt_m1W] => vm_compute; reflexivity
+ | _ => assumption
+ end;
+ cbv_in_all ();
+ apply H
+ end) in
+ rewrite <- correctness by solver (); clear correctness;
+ let lem := fresh in
+ pose proof eqbW_correct as lem; cbv_in_all (); rewrite <- lem by solver (); clear lem;
+ pose proof (pull_bool_if fe5211_32WToZ) as lem; cbv_in_all (); rewrite lem by solver (); clear lem;
+ subst_evars; reflexivity
end.
} Unfocus.
+ assert (Hfold : forall x, fe5211_32WToZ x = fe5211_32WToZ x) by reflexivity.
+ unfold fe5211_32WToZ at 2 in Hfold.
+ etransitivity.
+ Focus 2. {
+ apply Proper_Let_In_nd_changebody; [ reflexivity | intro ].
+ apply Hfold.
+ } Unfocus.
+ clear Hfold.
lazymatch goal with
| [ |- context G[dlet x := ?v in fe5211_32WToZ (@?f x)] ]
=> let G' := context G[fe5211_32WToZ (dlet x := v in f x)] in
@@ -346,15 +382,22 @@ Proof.
[ cbv [Let_In]; exact (fun x => x) | apply f_equal ]
| _ => idtac
end;
- reflexivity. }
- { cbv [Let_In];
+ reflexivity.
+ }
+
+ { cbv [Let_In HList.hlistP HList.hlistP'];
try break_if;
repeat lazymatch goal with
| [ |- is_bounded (?WToZ (powW _ _)) = true ]
=> apply powW_correct_and_bounded; assumption
- | [ |- is_bounded (?WToZ (mulW _ _)) = true ]
- => apply mulW_correct_and_bounded; [ vm_compute; reflexivity | ]
- end. }
+ | [ |- is_bounded (snd (?WToZ (_, powW _ _))) = true ]
+ => generalize powW_correct_and_bounded;
+ cbv [snd Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'];
+ let H := fresh in intro H; apply H; assumption
+ | [ |- is_bounded (?WToZ (mulW (_, _))) = true ]
+ => apply mulW_correct_and_bounded; split; [ vm_compute; reflexivity | ]
+ end.
+ }
Defined.
Definition sqrtW (f : fe5211_32W) : fe5211_32W :=
@@ -394,7 +437,7 @@ Proof. define_unop_WireToFE f unpackW unpackW_correct_and_bounded. Defined.
Definition pow (f : fe5211_32) (chain : list (nat * nat)) : fe5211_32.
Proof. define_unop f (fun x => powW x chain) powW_correct_and_bounded. Defined.
Definition inv (f : fe5211_32) : fe5211_32.
-Proof. define_unop f invW invW_correct_and_bounded. Defined.
+Proof. define_unop f invW (fun x p => proj2 (invW_correct_and_bounded x p)). Defined.
Definition sqrt (f : fe5211_32) : fe5211_32.
Proof. define_unop f sqrtW sqrtW_correct_and_bounded. Defined.
@@ -407,7 +450,12 @@ Local Ltac op_correct_t op opW_correct_and_bounded :=
=> rewrite proj1_wire_digits_exist_wire_digitsW
| _ => idtac
end;
- apply opW_correct_and_bounded;
+ generalize opW_correct_and_bounded;
+ cbv_tuple_map;
+ cbv [fst snd];
+ let H := fresh in
+ intro H; apply H;
+ repeat match goal with |- and _ _ => apply conj end;
lazymatch goal with
| [ |- is_bounded _ = true ]
=> apply is_bounded_proj1_fe5211_32
@@ -434,7 +482,7 @@ Proof. op_correct_t unpack unpackW_correct_and_bounded. Qed.
Lemma pow_correct (f : fe5211_32) chain : proj1_fe5211_32 (pow f chain) = GF5211_32.pow (proj1_fe5211_32 f) chain.
Proof. op_correct_t pow (powW_correct_and_bounded chain). Qed.
Lemma inv_correct (f : fe5211_32) : proj1_fe5211_32 (inv f) = GF5211_32.inv (proj1_fe5211_32 f).
-Proof. op_correct_t inv invW_correct_and_bounded. Qed.
+Proof. op_correct_t inv (fun x p => proj1 (invW_correct_and_bounded x p)). Qed.
Lemma sqrt_correct (f : fe5211_32) : proj1_fe5211_32 (sqrt f) = GF5211_32sqrt (proj1_fe5211_32 f).
Proof. op_correct_t sqrt sqrtW_correct_and_bounded. Qed.
diff --git a/src/SpecificGen/GF5211_32BoundedAddCoordinates.v b/src/SpecificGen/GF5211_32BoundedAddCoordinates.v
index 17189f4d0..96dbea3de 100644
--- a/src/SpecificGen/GF5211_32BoundedAddCoordinates.v
+++ b/src/SpecificGen/GF5211_32BoundedAddCoordinates.v
@@ -14,7 +14,7 @@ Local Ltac define_binop f g opW blem :=
Local Opaque Let_In.
Local Opaque Z.add Z.sub Z.mul Z.shiftl Z.shiftr Z.land Z.lor Z.eqb NToWord64.
-Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
+(*Local Arguments interp_radd_coordinates / _ _ _ _ _ _ _ _ _.
Definition add_coordinatesW (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe5211_32W) : Tuple.tuple fe5211_32W 4
:= Eval simpl in interp_radd_coordinates x0 x1 x2 x3 x4 x5 x6 x7 x8.
@@ -75,3 +75,4 @@ Lemma add_coordinates_correct (x0 x1 x2 x3 x4 x5 x6 x7 x8 : fe5211_32)
(proj1_fe5211_32 x7)
(proj1_fe5211_32 x8).
Proof. op_correct_t add_coordinates add_coordinatesW_correct_and_bounded. Qed.
+*)
diff --git a/src/SpecificGen/GF5211_32BoundedCommon.v b/src/SpecificGen/GF5211_32BoundedCommon.v
index 20e8c84fd..2ecc4ed1c 100644
--- a/src/SpecificGen/GF5211_32BoundedCommon.v
+++ b/src/SpecificGen/GF5211_32BoundedCommon.v
@@ -322,14 +322,14 @@ Ltac unfold_is_bounded_in' H :=
end.
Ltac preunfold_is_bounded_in H :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe5211_32WToZ, wire_digitsWToZ in H;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe5211_32 List.length wire_widths] in H.
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe5211_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple] in H.
Ltac unfold_is_bounded_in H :=
preunfold_is_bounded_in H;
unfold_is_bounded_in' H.
Ltac preunfold_is_bounded :=
unfold is_bounded, wire_digits_is_bounded, is_bounded_gen, fe5211_32WToZ, wire_digitsWToZ;
- cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 List.map fold_right List.rev List.app length_fe5211_32 List.length wire_widths].
+ cbv [to_list length bounds wire_digit_bounds from_list from_list' map2 on_tuple2 to_list' ListUtil.map2 Tuple.map List.map fold_right List.rev List.app length_fe5211_32 List.length wire_widths HList.hlistP HList.hlistP' Tuple.on_tuple].
Ltac unfold_is_bounded :=
preunfold_is_bounded;
@@ -724,7 +724,7 @@ Notation in_op_correct_and_bounded k irop op
/\ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=k) fe5211_32WToZ irop))%type)
(only parsing).
-Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
+(*Fixpoint inm_op_correct_and_bounded' (count_in count_out : nat)
: forall (irop : Tower.tower_nd fe5211_32W (Tuple.tuple fe5211_32W count_out) count_in)
(op : Tower.tower_nd GF5211_32.fe5211_32 (Tuple.tuple GF5211_32.fe5211_32 count_out) count_in)
(cont : Prop -> Prop),
@@ -792,18 +792,14 @@ Qed.
Definition inm_op_correct_and_bounded1 count_in irop op
:= Eval cbv [inm_op_correct_and_bounded Tuple.map Tuple.to_list Tuple.to_list' Tuple.from_list Tuple.from_list' Tuple.on_tuple List.map] in
- inm_op_correct_and_bounded count_in 1 irop op.
-Notation ibinop_correct_and_bounded irop op
- := (forall x y,
- is_bounded (fe5211_32WToZ x) = true
- -> is_bounded (fe5211_32WToZ y) = true
- -> fe5211_32WToZ (irop x y) = op (fe5211_32WToZ x) (fe5211_32WToZ y)
- /\ is_bounded (fe5211_32WToZ (irop x y)) = true) (only parsing).
-Notation iunop_correct_and_bounded irop op
- := (forall x,
- is_bounded (fe5211_32WToZ x) = true
- -> fe5211_32WToZ (irop x) = op (fe5211_32WToZ x)
- /\ is_bounded (fe5211_32WToZ (irop x)) = true) (only parsing).
+ inm_op_correct_and_bounded count_in 1 irop op.*)
+Notation inm_op_correct_and_bounded n m irop op
+ := ((forall x,
+ HList.hlistP (fun v => is_bounded v = true) (Tuple.map (n:=n%nat%type) fe5211_32WToZ x)
+ -> in_op_correct_and_bounded m (irop x) (op (Tuple.map (n:=n) fe5211_32WToZ x))))
+ (only parsing).
+Notation ibinop_correct_and_bounded irop op := (inm_op_correct_and_bounded 2 1 irop op) (only parsing).
+Notation iunop_correct_and_bounded irop op := (inm_op_correct_and_bounded 1 1 irop op) (only parsing).
Notation iunop_FEToZ_correct irop op
:= (forall x,
is_bounded (fe5211_32WToZ x) = true
@@ -818,20 +814,6 @@ Notation iunop_WireToFE_correct_and_bounded irop op
wire_digits_is_bounded (wire_digitsWToZ x) = true
-> fe5211_32WToZ (irop x) = op (wire_digitsWToZ x)
/\ is_bounded (fe5211_32WToZ (irop x)) = true) (only parsing).
-Notation i9top_correct_and_bounded k irop op
- := ((forall x0 x1 x2 x3 x4 x5 x6 x7 x8,
- is_bounded (fe5211_32WToZ x0) = true
- -> is_bounded (fe5211_32WToZ x1) = true
- -> is_bounded (fe5211_32WToZ x2) = true
- -> is_bounded (fe5211_32WToZ x3) = true
- -> is_bounded (fe5211_32WToZ x4) = true
- -> is_bounded (fe5211_32WToZ x5) = true
- -> is_bounded (fe5211_32WToZ x6) = true
- -> is_bounded (fe5211_32WToZ x7) = true
- -> is_bounded (fe5211_32WToZ x8) = true
- -> (Tuple.map (n:=k) fe5211_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)
- = op (fe5211_32WToZ x0) (fe5211_32WToZ x1) (fe5211_32WToZ x2) (fe5211_32WToZ x3) (fe5211_32WToZ x4) (fe5211_32WToZ x5) (fe5211_32WToZ x6) (fe5211_32WToZ x7) (fe5211_32WToZ x8))
- * HList.hlist (fun v => is_bounded v = true) (Tuple.map (n:=k) fe5211_32WToZ (irop x0 x1 x2 x3 x4 x5 x6 x7 x8)))%type)
- (only parsing).
+Notation i9top_correct_and_bounded k irop op := (inm_op_correct_and_bounded 9 k irop op) (only parsing).
-Definition prefreeze := GF5211_32.prefreeze.
+Notation prefreeze := GF5211_32.prefreeze.
diff --git a/src/SpecificGen/GF5211_32BoundedExtendedAddCoordinates.v b/src/SpecificGen/GF5211_32BoundedExtendedAddCoordinates.v
index f6ba06ec6..4fafe3a10 100644
--- a/src/SpecificGen/GF5211_32BoundedExtendedAddCoordinates.v
+++ b/src/SpecificGen/GF5211_32BoundedExtendedAddCoordinates.v
@@ -5,7 +5,7 @@ Require Import Crypto.SpecificGen.GF5211_32ExtendedAddCoordinates.
Require Import Crypto.SpecificGen.GF5211_32BoundedAddCoordinates.
Require Import Crypto.Util.Tuple.
Require Import Crypto.Util.Tactics.
-
+(*
Lemma fieldwise_eq_extended_add_coordinates_full' twice_d P10 P11 P12 P13 P20 P21 P22 P23
: Tuple.fieldwise
(n:=4) GF5211_32BoundedCommon.eq
@@ -65,3 +65,4 @@ Proof.
destruct_head' prod.
rewrite <- fieldwise_eq_extended_add_coordinates_full'; reflexivity.
Qed.
+*)
diff --git a/src/SpecificGen/GF5211_32Reflective.v b/src/SpecificGen/GF5211_32Reflective.v
index fe29cae6a..f6f70ffec 100644
--- a/src/SpecificGen/GF5211_32Reflective.v
+++ b/src/SpecificGen/GF5211_32Reflective.v
@@ -45,6 +45,7 @@ Declare Reduction asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe5211_32W curry_unop_fe5211_32W curry_unop_wire_digitsW curry_9op_fe5211_32W
WordW.interp_op WordW.interp_base_type
@@ -56,6 +57,7 @@ Ltac asm_interp
:= cbv beta iota delta
[id
interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ Eta.interp_flat_type_eta Eta.interp_flat_type_eta_gen
radd rsub rmul ropp rprefreeze rge_modulus rpack runpack
curry_binop_fe5211_32W curry_unop_fe5211_32W curry_unop_wire_digitsW curry_9op_fe5211_32W
WordW.interp_op WordW.interp_base_type
@@ -65,15 +67,15 @@ Ltac asm_interp
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-Definition interp_radd : SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
+Definition interp_radd : SpecificGen.GF5211_32BoundedCommon.fe5211_32W * SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
:= Eval asm_interp in interp_bexpr radd.
(*Print interp_radd.*)
Definition interp_radd_correct : interp_radd = interp_bexpr radd := eq_refl.
-Definition interp_rsub : SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
+Definition interp_rsub : SpecificGen.GF5211_32BoundedCommon.fe5211_32W * SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
:= Eval asm_interp in interp_bexpr rsub.
(*Print interp_rsub.*)
Definition interp_rsub_correct : interp_rsub = interp_bexpr rsub := eq_refl.
-Definition interp_rmul : SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
+Definition interp_rmul : SpecificGen.GF5211_32BoundedCommon.fe5211_32W * SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
:= Eval asm_interp in interp_bexpr rmul.
(*Print interp_rmul.*)
Definition interp_rmul_correct : interp_rmul = interp_bexpr rmul := eq_refl.
diff --git a/src/SpecificGen/GF5211_32Reflective/Common.v b/src/SpecificGen/GF5211_32Reflective/Common.v
index 2ea85da7f..176e20f08 100644
--- a/src/SpecificGen/GF5211_32Reflective/Common.v
+++ b/src/SpecificGen/GF5211_32Reflective/Common.v
@@ -7,7 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Wf.
Require Import Crypto.Reflection.ExprInversion.
+Require Import Crypto.Reflection.Tuple.
Require Import Crypto.Reflection.Relations.
+Require Import Crypto.Reflection.Eta.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -15,13 +17,14 @@ Require Import Crypto.Reflection.Z.Reify.
Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.Z.Syntax.Equality.
Require Import Crypto.Reflection.InterpWfRel.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Util.Curry.
Require Import Crypto.Util.Tower.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.ListUtil.
Require Import Crypto.Util.ZUtil.
Require Import Crypto.Util.Tactics.
+Require Import Crypto.Util.Prod.
Require Import Crypto.Util.Notations.
Notation Expr := (Expr base_type op).
@@ -43,30 +46,24 @@ Defined.
Definition Expr_n_OpT (count_out : nat) : flat_type base_type
:= Eval cbv [Syntax.tuple Syntax.tuple' fe5211_32T] in
Syntax.tuple fe5211_32T count_out.
-Fixpoint Expr_nm_OpT (count_in count_out : nat) : type base_type
- := match count_in with
- | 0 => Expr_n_OpT count_out
- | S n => SmartArrow fe5211_32T (Expr_nm_OpT n count_out)
- end.
+Definition Expr_nm_OpT (count_in count_out : nat) : type base_type
+ := Eval cbv [Syntax.tuple Syntax.tuple' fe5211_32T Expr_n_OpT] in
+ Arrow (Syntax.tuple fe5211_32T count_in) (Expr_n_OpT count_out).
Definition ExprBinOpT : type base_type := Eval compute in Expr_nm_OpT 2 1.
Definition ExprUnOpT : type base_type := Eval compute in Expr_nm_OpT 1 1.
Definition ExprUnOpFEToZT : type base_type.
-Proof. make_type_from (uncurry_unop_fe5211_32 ge_modulus). Defined.
+Proof. make_type_from ge_modulus. Defined.
Definition ExprUnOpWireToFET : type base_type.
-Proof. make_type_from (uncurry_unop_wire_digits unpack). Defined.
+Proof. make_type_from unpack. Defined.
Definition ExprUnOpFEToWireT : type base_type.
-Proof. make_type_from (uncurry_unop_fe5211_32 pack). Defined.
+Proof. make_type_from pack. Defined.
Definition Expr4OpT : type base_type := Eval compute in Expr_nm_OpT 4 1.
Definition Expr9_4OpT : type base_type := Eval compute in Expr_nm_OpT 9 4.
Definition ExprArgT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpT.
+ := Eval compute in domain ExprUnOpT.
Definition ExprArgWireT : flat_type base_type
- := Eval compute in remove_all_binders ExprUnOpFEToWireT.
-Definition ExprArgRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpT.
-Definition ExprArgWireRevT : flat_type base_type
- := Eval compute in all_binders_for ExprUnOpWireToFET.
-Definition ExprZ : Type := Expr (Tbase TZ).
+ := Eval compute in domain ExprUnOpWireToFET.
+Definition ExprZ : Type := Expr (Arrow Unit (Tbase TZ)).
Definition ExprUnOpFEToZ : Type := Expr ExprUnOpFEToZT.
Definition ExprUnOpWireToFE : Type := Expr ExprUnOpWireToFET.
Definition ExprUnOpFEToWire : Type := Expr ExprUnOpFEToWireT.
@@ -75,99 +72,67 @@ Definition ExprBinOp : Type := Expr ExprBinOpT.
Definition ExprUnOp : Type := Expr ExprUnOpT.
Definition Expr4Op : Type := Expr Expr4OpT.
Definition Expr9_4Op : Type := Expr Expr9_4OpT.
-Definition ExprArg : Type := Expr ExprArgT.
-Definition ExprArgWire : Type := Expr ExprArgWireT.
-Definition ExprArgRev : Type := Expr ExprArgRevT.
-Definition ExprArgWireRev : Type := Expr ExprArgWireRevT.
+Definition ExprArg : Type := Expr (Arrow Unit ExprArgT).
+Definition ExprArgWire : Type := Expr (Arrow Unit ExprArgWireT).
Definition expr_nm_Op count_in count_out var : Type
:= expr base_type op (var:=var) (Expr_nm_OpT count_in count_out).
Definition exprBinOp var : Type := expr base_type op (var:=var) ExprBinOpT.
Definition exprUnOp var : Type := expr base_type op (var:=var) ExprUnOpT.
Definition expr4Op var : Type := expr base_type op (var:=var) Expr4OpT.
Definition expr9_4Op var : Type := expr base_type op (var:=var) Expr9_4OpT.
-Definition exprZ var : Type := expr base_type op (var:=var) (Tbase TZ).
+Definition exprZ var : Type := expr base_type op (var:=var) (Arrow Unit (Tbase TZ)).
Definition exprUnOpFEToZ var : Type := expr base_type op (var:=var) ExprUnOpFEToZT.
Definition exprUnOpWireToFE var : Type := expr base_type op (var:=var) ExprUnOpWireToFET.
Definition exprUnOpFEToWire var : Type := expr base_type op (var:=var) ExprUnOpFEToWireT.
-Definition exprArg var : Type := expr base_type op (var:=var) ExprArgT.
-Definition exprArgWire var : Type := expr base_type op (var:=var) ExprArgWireT.
-Definition exprArgRev var : Type := expr base_type op (var:=var) ExprArgRevT.
-Definition exprArgWireRev var : Type := expr base_type op (var:=var) ExprArgWireRevT.
-
-Local Ltac bounds_from_list_cps ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(fun T (extra : T) => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, extra))
- | (?x :: ?xs)%list => let bs := bounds_from_list_cps xs in
- constr:(fun T extra => (Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs T extra))
- end.
-
-Local Ltac make_bounds_cps ls extra :=
- let v := bounds_from_list_cps (List.rev ls) in
- let v := (eval compute in v) in
- exact (v _ extra).
-
-Local Ltac bounds_from_list ls :=
- lazymatch (eval hnf in ls) with
- | (?x :: nil)%list => constr:(Some {| Bounds.lower := fst x ; Bounds.upper := snd x |})
- | (?x :: ?xs)%list => let bs := bounds_from_list xs in
- constr:((Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}, bs))
- end.
-
-Local Ltac make_bounds ls :=
- compute;
- let v := bounds_from_list (List.rev ls) in
- let v := (eval compute in v) in
- exact v.
-
-Fixpoint Expr_nm_Op_bounds count_in count_out : interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type.
-Proof.
- refine match count_in return interp_all_binders_for (Expr_nm_OpT count_in count_out) ZBounds.interp_base_type with
- | 0 => tt
- | S n => let v := interp_all_binders_for_to' (Expr_nm_Op_bounds n count_out) in
- interp_all_binders_for_of' _
- end; simpl.
- make_bounds_cps (Tuple.to_list _ bounds) v.
-Defined.
-Definition ExprBinOp_bounds : interp_all_binders_for ExprBinOpT ZBounds.interp_base_type
+Definition exprArg var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgT).
+Definition exprArgWire var : Type := expr base_type op (var:=var) (Arrow Unit ExprArgWireT).
+
+Definition make_bound (x : Z * Z) : ZBounds.t
+ := Some {| Bounds.lower := fst x ; Bounds.upper := snd x |}.
+
+Fixpoint Expr_nm_Op_bounds count_in count_out {struct count_in} : interp_flat_type ZBounds.interp_base_type (domain (Expr_nm_OpT count_in count_out))
+ := match count_in return interp_flat_type _ (domain (Expr_nm_OpT count_in count_out)) with
+ | 0 => tt
+ | S n
+ => let b := (Tuple.map make_bound bounds) in
+ let bs := Expr_nm_Op_bounds n count_out in
+ match n return interp_flat_type _ (domain (Expr_nm_OpT n _)) -> interp_flat_type _ (domain (Expr_nm_OpT (S n) _)) with
+ | 0 => fun _ => b
+ | S n' => fun bs => (bs, b)
+ end bs
+ end.
+Definition ExprBinOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprBinOpT)
:= Eval compute in Expr_nm_Op_bounds 2 1.
-Definition ExprUnOp_bounds : interp_all_binders_for ExprUnOpT ZBounds.interp_base_type
+Definition ExprUnOp_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToZ_bounds : interp_all_binders_for ExprUnOpFEToZT ZBounds.interp_base_type
+Definition ExprUnOpFEToZ_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToZT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition ExprUnOpFEToWire_bounds : interp_all_binders_for ExprUnOpFEToWireT ZBounds.interp_base_type
+Definition ExprUnOpFEToWire_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpFEToWireT)
:= Eval compute in Expr_nm_Op_bounds 1 1.
-Definition Expr4Op_bounds : interp_all_binders_for Expr4OpT ZBounds.interp_base_type
+Definition Expr4Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr4OpT)
:= Eval compute in Expr_nm_Op_bounds 4 1.
-Definition Expr9Op_bounds : interp_all_binders_for Expr9_4OpT ZBounds.interp_base_type
+Definition Expr9Op_bounds : interp_flat_type ZBounds.interp_base_type (domain Expr9_4OpT)
:= Eval compute in Expr_nm_Op_bounds 9 4.
-Definition ExprUnOpWireToFE_bounds : interp_all_binders_for ExprUnOpWireToFET ZBounds.interp_base_type.
-Proof. make_bounds (Tuple.to_list _ wire_digit_bounds). Defined.
+Definition ExprUnOpWireToFE_bounds : interp_flat_type ZBounds.interp_base_type (domain ExprUnOpWireToFET)
+ := Tuple.map make_bound wire_digit_bounds.
-Definition interp_bexpr : ExprBinOp -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- := fun e => curry_binop_fe5211_32W (Interp (@WordW.interp_op) e).
+Definition interp_bexpr : ExprBinOp -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W * SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr : ExprUnOp -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- := fun e => curry_unop_fe5211_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToZ : ExprUnOpFEToZ -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.word64
- := fun e => curry_unop_fe5211_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_FEToWire : ExprUnOpFEToWire -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W -> SpecificGen.GF5211_32BoundedCommon.wire_digitsW
- := fun e => curry_unop_fe5211_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_uexpr_WireToFE : ExprUnOpWireToFE -> SpecificGen.GF5211_32BoundedCommon.wire_digitsW -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- := fun e => curry_unop_wire_digitsW (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Definition interp_9_4expr : Expr9_4Op
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
- -> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
+ -> Tuple.tuple SpecificGen.GF5211_32BoundedCommon.fe5211_32W 9
-> Tuple.tuple SpecificGen.GF5211_32BoundedCommon.fe5211_32W 4
- := fun e => curry_9op_fe5211_32W (Interp (@WordW.interp_op) e).
+ := fun e => interp_flat_type_eta (Interp (@WordW.interp_op) e).
Notation binop_correct_and_bounded rop op
- := (ibinop_correct_and_bounded (interp_bexpr rop) op) (only parsing).
+ := (ibinop_correct_and_bounded (interp_bexpr rop) (curry2 op)) (only parsing).
Notation unop_correct_and_bounded rop op
:= (iunop_correct_and_bounded (interp_uexpr rop) op) (only parsing).
Notation unop_FEToZ_correct rop op
@@ -181,40 +146,39 @@ Notation op9_4_correct_and_bounded rop op
Ltac rexpr_cbv :=
lazymatch goal with
- | [ |- { rexpr | interp_type_gen_rel_pointwise _ (Interp _ (t:=?T) rexpr) (?uncurry ?oper) } ]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?uncurry ?oper x } ]
=> let operf := head oper in
let uncurryf := head uncurry in
try cbv delta [T]; try cbv delta [oper];
try cbv beta iota delta [uncurryf]
+ | [ |- { rexpr | forall x, Interp _ (t:=?T) rexpr x = ?oper x } ]
+ => let operf := head oper in
+ try cbv delta [T]; try cbv delta [oper]
end;
- cbv beta iota delta [interp_flat_type Z.interp_base_type interp_base_type zero_].
+ cbv beta iota delta [interp_flat_type interp_base_type zero_ GF5211_32.fe5211_32 GF5211_32.wire_digits].
Ltac reify_sig :=
rexpr_cbv; eexists; Reify_rhs; reflexivity.
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ
- | interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op }
+ | forall x, Interp interp_op (t:=T) rexprZ x = uncurried_op x }
(only parsing).
-Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (uncurry_binop_fe5211_32 op)) (only parsing).
-Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT (uncurry_unop_fe5211_32 op)) (only parsing).
-Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT (uncurry_unop_fe5211_32 op)) (only parsing).
-Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT (uncurry_unop_fe5211_32 op)) (only parsing).
-Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET (uncurry_unop_wire_digits op)) (only parsing).
-Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT (uncurry_9op_fe5211_32 op)) (only parsing).
+Notation rexpr_binop_sig op := (rexpr_sig ExprBinOpT (curry2 op)) (only parsing).
+Notation rexpr_unop_sig op := (rexpr_sig ExprUnOpT op) (only parsing).
+Notation rexpr_unop_FEToZ_sig op := (rexpr_sig ExprUnOpFEToZT op) (only parsing).
+Notation rexpr_unop_FEToWire_sig op := (rexpr_sig ExprUnOpFEToWireT op) (only parsing).
+Notation rexpr_unop_WireToFE_sig op := (rexpr_sig ExprUnOpWireToFET op) (only parsing).
+Notation rexpr_9_4op_sig op := (rexpr_sig Expr9_4OpT op) (only parsing).
Notation correct_and_bounded_genT ropW'v ropZ_sigv
:= (let ropW' := ropW'v in
let ropZ_sig := ropZ_sigv in
- let ropW := ropW' in
- let ropZ := ropW' in
- let ropBounds := ropW' in
- let ropBoundedWordW := ropW' in
- ropZ = proj1_sig ropZ_sig
- /\ interp_type_rel_pointwise2 Relations.related_Z (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@Z.interp_op) ropZ)
- /\ interp_type_rel_pointwise2 Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@ZBounds.interp_op) ropBounds)
- /\ interp_type_rel_pointwise2 Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropBoundedWordW) (Interp (@WordW.interp_op) ropW))
+ ropW' = proj1_sig ropZ_sig
+ /\ interp_type_rel_pointwise Relations.related_Z (Interp (@BoundedWordW.interp_op) ropW') (Interp (@Z.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_bounds (Interp (@BoundedWordW.interp_op) ropW') (Interp (@ZBounds.interp_op) ropW')
+ /\ interp_type_rel_pointwise Relations.related_wordW (Interp (@BoundedWordW.interp_op) ropW') (Interp (@WordW.interp_op) ropW'))
(only parsing).
Ltac app_tuples x y :=
@@ -227,7 +191,7 @@ Ltac app_tuples x y :=
Local Arguments Tuple.map2 : simpl never.
Local Arguments Tuple.map : simpl never.
-
+(*
Fixpoint args_to_bounded_helperT {n}
(v : Tuple.tuple' WordW.wordW n)
(bounds : Tuple.tuple' (Z * Z) n)
@@ -299,14 +263,15 @@ Proof.
Z.ltb_to_lt; auto
). }
Defined.
+*)
Definition assoc_right''
:= Eval cbv [Tuple.assoc_right' Tuple.rsnoc' fst snd] in @Tuple.assoc_right'.
-
+(*
Definition args_to_bounded {n} v bounds pf
:= Eval cbv [args_to_bounded_helper assoc_right''] in
@args_to_bounded_helper n _ v bounds pf (@assoc_right'' _ _).
-
+*)
Local Ltac get_len T :=
match (eval hnf in T) with
| prod ?A ?B
@@ -327,6 +292,7 @@ Ltac assoc_right_tuple x so_far :=
end
end.
+(*
Local Ltac make_args x :=
let x' := fresh "x'" in
compute in x |- *;
@@ -338,11 +304,6 @@ Local Ltac make_args x :=
let xv := assoc_right_tuple x'' (@None) in
refine (SmartVarf (xv : interp_flat_type _ t')).
-Definition unop_make_args {var} (x : exprArg var) : exprArgRev var.
-Proof. make_args x. Defined.
-Definition unop_wire_make_args {var} (x : exprArgWire var) : exprArgWireRev var.
-Proof. make_args x. Defined.
-
Local Ltac args_to_bounded x H :=
let x' := fresh in
set (x' := x);
@@ -351,29 +312,138 @@ Local Ltac args_to_bounded x H :=
destruct_head' prod;
let c := constr:(args_to_bounded (n:=pred len) x' _ H) in
let bounds := lazymatch c with args_to_bounded _ ?bounds _ => bounds end in
- let c := (eval cbv [all_binders_for ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
+ let c := (eval cbv [domain ExprUnOpT interp_flat_type args_to_bounded bounds pred fst snd] in c) in
apply c; compute; clear;
try abstract (
repeat split;
solve [ reflexivity
| refine (fun v => match v with eq_refl => I end) ]
).
+ *)
+
+Section gen.
+ Definition bounds_are_good_gen
+ {n : nat} (bounds : Tuple.tuple (Z * Z) n)
+ := let res :=
+ Tuple.map (fun bs => let '(lower, upper) := bs in ((0 <=? lower)%Z && (Z.log2 upper <? Z.of_nat WordW.bit_width)%Z)%bool) bounds
+ in
+ List.fold_right andb true (Tuple.to_list n res).
+ Definition unop_args_to_bounded'
+ (bs : Z * Z)
+ (Hbs : bounds_are_good_gen (n:=1) bs = true)
+ (x : word64)
+ (H : is_bounded_gen (Tuple.map (fun v : word64 => (v : Z)) (n:=1) x) bs = true)
+ : BoundedWordW.BoundedWord.
+ Proof.
+ refine {| BoundedWord.lower := fst bs ; BoundedWord.value := x ; BoundedWord.upper := snd bs |}.
+ unfold bounds_are_good_gen, is_bounded_gen, Tuple.map, Tuple.map2 in *; simpl in *.
+ abstract (
+ destruct bs; Bool.split_andb; Z.ltb_to_lt; simpl;
+ repeat apply conj; assumption
+ ).
+ Defined.
+ Fixpoint n_op_args_to_bounded'
+ n
+ : forall (bs : Tuple.tuple' (Z * Z) n)
+ (Hbs : bounds_are_good_gen (n:=S n) bs = true)
+ (x : Tuple.tuple' word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (n:=S n) (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Tbase TZ) n).
+ Proof.
+ destruct n as [|n']; simpl in *.
+ { exact unop_args_to_bounded'. }
+ { refine (fun bs Hbs x H
+ => (@n_op_args_to_bounded' n' (fst bs) _ (fst x) _,
+ @unop_args_to_bounded' (snd bs) _ (snd x) _));
+ clear n_op_args_to_bounded';
+ simpl in *;
+ [ clear x H | clear Hbs | clear x H | clear Hbs ];
+ unfold bounds_are_good_gen, is_bounded_gen in *;
+ abstract (
+ repeat first [ progress simpl in *
+ | assumption
+ | reflexivity
+ | progress Bool.split_andb
+ | progress destruct_head prod
+ | match goal with
+ | [ H : _ |- _ ] => progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep in H
+ end
+ | progress rewrite ?Tuple.map_S, ?Tuple.map2_S, ?Tuple.strip_eta_tuple'_dep
+ | progress break_match_hyps
+ | rewrite Bool.andb_true_iff; apply conj
+ | unfold Tuple.map, Tuple.map2; simpl; rewrite Bool.andb_true_iff; apply conj ]
+ ). }
+ Defined.
+
+ Definition n_op_args_to_bounded
+ n
+ : forall (bs : Tuple.tuple (Z * Z) n)
+ (Hbs : bounds_are_good_gen bs = true)
+ (x : Tuple.tuple word64 n)
+ (H : is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Tbase TZ) n)
+ := match n with
+ | 0 => fun _ _ _ _ => tt
+ | S n' => @n_op_args_to_bounded' n'
+ end.
-Definition unop_args_to_bounded (x : fe5211_32W) (H : is_bounded (fe5211_32WToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpT).
-Proof. args_to_bounded x H. Defined.
+ Fixpoint nm_op_args_to_bounded' n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple' (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple' (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => @n_op_args_to_bounded m bs Hbs
+ | S n' => fun x H
+ => (@nm_op_args_to_bounded' n' m bs Hbs (fst x) (proj1 H),
+ @n_op_args_to_bounded m bs Hbs (snd x) (proj2 H))
+ end.
+ Definition nm_op_args_to_bounded n m
+ (bs : Tuple.tuple (Z * Z) m)
+ (Hbs : bounds_are_good_gen bs = true)
+ : forall (x : interp_flat_type (fun _ => Tuple.tuple word64 m) (Syntax.tuple (Tbase TZ) n))
+ (H : SmartVarfPropMap (fun _ x => is_bounded_gen (Tuple.eta_tuple (Tuple.map (fun v : word64 => v : Z)) x) bs = true)
+ x),
+ interp_flat_type (fun _ => BoundedWordW.BoundedWord) (Syntax.tuple (Syntax.tuple (Tbase TZ) m) n)
+ := match n with
+ | 0 => fun _ _ => tt
+ | S n' => @nm_op_args_to_bounded' n' m bs Hbs
+ end.
+End gen.
+
+Local Ltac get_inner_len T :=
+ lazymatch T with
+ | (?T * _)%type => get_inner_len T
+ | ?T => get_len T
+ end.
+Local Ltac get_outer_len T :=
+ lazymatch T with
+ | (?A * ?B)%type => let a := get_outer_len A in
+ let b := get_outer_len B in
+ (eval compute in (a + b)%nat)
+ | ?T => constr:(1%nat)
+ end.
+Local Ltac args_to_bounded x H :=
+ let t := type of x in
+ let m := get_inner_len t in
+ let n := get_outer_len t in
+ let H := constr:(fun Hbs => @nm_op_args_to_bounded n m _ Hbs x H) in
+ let H := (eval cbv beta in (H eq_refl)) in
+ exact H.
-Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprUnOpWireToFET).
-Proof. args_to_bounded x H. Defined.
Definition binop_args_to_bounded (x : fe5211_32W * fe5211_32W)
(H : is_bounded (fe5211_32WToZ (fst x)) = true)
(H' : is_bounded (fe5211_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for ExprBinOpT).
-Proof.
- let v := app_tuples (unop_args_to_bounded (fst x) H) (unop_args_to_bounded (snd x) H') in
- exact v.
-Defined.
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprBinOpT).
+Proof. args_to_bounded x (conj H H'). Defined.
+Definition unop_args_to_bounded (x : fe5211_32W) (H : is_bounded (fe5211_32WToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpT).
+Proof. args_to_bounded x H. Defined.
+Definition unopWireToFE_args_to_bounded (x : wire_digitsW) (H : wire_digits_is_bounded (wire_digitsWToZ x) = true)
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain ExprUnOpWireToFET).
+Proof. args_to_bounded x H. Defined.
Definition op9_args_to_bounded (x : fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W * fe5211_32W)
(H0 : is_bounded (fe5211_32WToZ (fst (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
(H1 : is_bounded (fe5211_32WToZ (snd (fst (fst (fst (fst (fst (fst (fst x))))))))) = true)
@@ -384,58 +454,39 @@ Definition op9_args_to_bounded (x : fe5211_32W * fe5211_32W * fe5211_32W * fe521
(H6 : is_bounded (fe5211_32WToZ (snd (fst (fst x)))) = true)
(H7 : is_bounded (fe5211_32WToZ (snd (fst x))) = true)
(H8 : is_bounded (fe5211_32WToZ (snd x)) = true)
- : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (all_binders_for Expr9_4OpT).
-Proof.
- let v := constr:(unop_args_to_bounded _ H8) in
- let v := app_tuples (unop_args_to_bounded _ H7) v in
- let v := app_tuples (unop_args_to_bounded _ H6) v in
- let v := app_tuples (unop_args_to_bounded _ H5) v in
- let v := app_tuples (unop_args_to_bounded _ H4) v in
- let v := app_tuples (unop_args_to_bounded _ H3) v in
- let v := app_tuples (unop_args_to_bounded _ H2) v in
- let v := app_tuples (unop_args_to_bounded _ H1) v in
- let v := app_tuples (unop_args_to_bounded _ H0) v in
- exact v.
-Defined.
-
+ : interp_flat_type (fun _ => BoundedWordW.BoundedWord) (domain Expr9_4OpT).
+Proof. args_to_bounded x (conj (conj (conj (conj (conj (conj (conj (conj H0 H1) H2) H3) H4) H5) H6) H7) H8). Defined.
+Local Ltac make_bounds_prop' bounds bounds' :=
+ first [ refine (andb _ _);
+ [ destruct bounds' as [bounds' _], bounds as [bounds _]
+ | destruct bounds' as [_ bounds'], bounds as [_ bounds] ];
+ try make_bounds_prop' bounds bounds'
+ | exact (match bounds' with
+ | Some bounds' => let (l, u) := bounds in
+ let (l', u') := bounds' in
+ ((l' <=? l) && (u <=? u'))%Z%bool
+ | None => false
+ end) ].
Local Ltac make_bounds_prop bounds orig_bounds :=
let bounds' := fresh "bounds'" in
- let bounds_bad := fresh "bounds_bad" in
- rename bounds into bounds_bad;
- let boundsv := assoc_right_tuple bounds_bad (@None) in
- pose boundsv as bounds;
pose orig_bounds as bounds';
- repeat (refine (match fst bounds' with
- | Some bounds' => let (l, u) := fst bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end && _)%bool;
- destruct bounds' as [_ bounds'], bounds as [_ bounds]);
- try exact (match bounds' with
- | Some bounds' => let (l, u) := bounds in
- let (l', u') := bounds' in
- ((l' <=? l) && (u <=? u'))%Z%bool
- | None => false
- end).
-
-Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpT)) : bool.
+ make_bounds_prop' bounds bounds'.
+Definition unop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprBinOpT)) : bool.
+Definition binop_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprBinOpT)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
-Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToWireT)) : bool.
+Definition unopFEToWire_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToWireT)) : bool.
Proof. make_bounds_prop bounds ExprUnOpWireToFE_bounds. Defined.
-Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpWireToFET)) : bool.
+Definition unopWireToFE_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpWireToFET)) : bool.
Proof. make_bounds_prop bounds ExprUnOp_bounds. Defined.
(* TODO FIXME(jgross?, andreser?): Is every function returning a single Z a boolean function? *)
-Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders ExprUnOpFEToZT)) : bool.
+Definition unopFEToZ_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain ExprUnOpFEToZT)) : bool.
Proof.
refine (let (l, u) := bounds in ((0 <=? l) && (u <=? 1))%Z%bool).
Defined.
-Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (remove_all_binders Expr9_4OpT)) : bool.
+Definition op9_4_bounds_good (bounds : interp_flat_type (fun _ => ZBounds.bounds) (codomain Expr9_4OpT)) : bool.
Proof. make_bounds_prop bounds Expr4Op_bounds. Defined.
-
-Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
+(*Definition ApplyUnOp {var} (f : exprUnOp var) : exprArg var -> exprArg var
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe5211_32 f k)).
@@ -460,12 +511,11 @@ Definition ApplyUnOpFEToZ {var} (f : exprUnOpFEToZ var) : exprArg var -> exprZ v
:= fun x
=> LetIn (invert_Return (unop_make_args x))
(fun k => invert_Return (Apply length_fe5211_32 f k)).
-
+*)
(* FIXME TODO(jgross): This is a horrible tactic. We should unify the
various kinds of correct and boundedness, and abstract in Gallina
rather than Ltac *)
-
Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Heq := fresh "Heq" in
let Hbounds0 := fresh "Hbounds0" in
@@ -473,23 +523,25 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
let Hbounds2 := fresh "Hbounds2" in
pose proof (proj2_sig ropZ_sig) as Heq;
cbv [interp_bexpr interp_uexpr interp_uexpr_FEToWire interp_uexpr_FEToZ interp_uexpr_WireToFE interp_9_4expr
+ interp_flat_type_eta interp_flat_type_eta_gen
curry_binop_fe5211_32W curry_unop_fe5211_32W curry_unop_wire_digitsW curry_9op_fe5211_32W
curry_binop_fe5211_32 curry_unop_fe5211_32 curry_unop_wire_digits curry_9op_fe5211_32
uncurry_binop_fe5211_32W uncurry_unop_fe5211_32W uncurry_unop_wire_digitsW uncurry_9op_fe5211_32W
uncurry_binop_fe5211_32 uncurry_unop_fe5211_32 uncurry_unop_wire_digits uncurry_9op_fe5211_32
- ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT
- interp_type_gen_rel_pointwise interp_type_gen_rel_pointwise] in *;
+ ExprBinOpT ExprUnOpFEToWireT ExprUnOpT ExprUnOpFEToZT ExprUnOpWireToFET Expr9_4OpT Expr4OpT] in *;
cbv zeta in *;
simpl @fe5211_32WToZ; simpl @wire_digitsWToZ;
rewrite <- Heq; clear Heq;
destruct Hbounds as [Heq Hbounds];
change interp_op with (@Z.interp_op) in *;
change interp_base_type with (@Z.interp_base_type) in *;
+ change word64 with WordW.wordW in *;
rewrite <- Heq; clear Heq;
destruct Hbounds as [ Hbounds0 [Hbounds1 Hbounds2] ];
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
- pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise2_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj_from_option2 WordW.to_Z pf Hbounds2 Hbounds0) as Hbounds_left;
+ pose proof (fun pf => Relations.uncurry_interp_type_rel_pointwise_proj1_from_option2 Relations.related_wordW_boundsi' pf Hbounds1 Hbounds2) as Hbounds_right;
specialize_by repeat first [ progress intros
+ | progress unfold RelationClasses.Reflexive
| reflexivity
| assumption
| progress destruct_head' base_type
@@ -509,23 +561,33 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
repeat match goal with x := _ |- _ => subst x end;
cbv [id
binop_args_to_bounded unop_args_to_bounded unopWireToFE_args_to_bounded op9_args_to_bounded
- Relations.proj_eq_rel interp_flat_type_rel_pointwise SmartVarfMap interp_flat_type smart_interp_flat_map Application.all_binders_for fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Application.ApplyInterpedAll Application.ApplyInterpedAll' Application.interp_all_binders_for_of' Application.interp_all_binders_for_to' Application.fst_binder Application.snd_binder interp_flat_type_rel_pointwise_gen_Prop Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower Application.remove_all_binders WordW.to_Z] in Hbounds_left, Hbounds_right;
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list
+ Relations.proj_eq_rel SmartVarfMap interp_flat_type smart_interp_flat_map domain fst snd BoundedWordW.to_wordW' BoundedWordW.boundedWordToWordW BoundedWord.value Relations.related_wordW_boundsi' Relations.related'_wordW_bounds Bounds.upper Bounds.lower codomain WordW.to_Z nm_op_args_to_bounded nm_op_args_to_bounded' n_op_args_to_bounded n_op_args_to_bounded' unop_args_to_bounded' Relations.interp_flat_type_rel_pointwise Relations.interp_flat_type_rel_pointwise_gen_Prop] in Hbounds_left, Hbounds_right;
+ simpl @interp_flat_type in *;
+ (let v := (eval unfold WordW.interp_base_type in (WordW.interp_base_type TZ)) in
+ change (WordW.interp_base_type TZ) with v in *);
+ cbv beta iota zeta in *;
lazymatch goal with
| [ |- fe5211_32WToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
| [ |- wire_digitsWToZ ?x = _ /\ _ ]
=> generalize dependent x; intros
+ | [ |- (Tuple.map fe5211_32WToZ ?x = _) /\ _ ]
+ => generalize dependent x; intros
| [ |- ((Tuple.map fe5211_32WToZ ?x = _) * _)%type ]
=> generalize dependent x; intros
| [ |- _ = _ ]
=> exact Hbounds_left
end;
- cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type remove_all_binders] in *;
+ cbv [interp_type interp_type_gen interp_type_gen_hetero interp_flat_type WordW.interp_base_type codomain] in *;
destruct_head' prod;
change word64ToZ with WordW.wordWToZ in *;
(split; [ exact Hbounds_left | ]);
cbv [interp_flat_type] in *;
cbv [fst snd
+ Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' List.map Tuple.from_list Tuple.from_list Tuple.from_list'
+ make_bound
+ Datatypes.length wire_widths wire_digit_bounds PseudoMersenneBaseParams.limb_widths bounds
binop_bounds_good unop_bounds_good unopFEToWire_bounds_good unopWireToFE_bounds_good unopFEToZ_bounds_good op9_4_bounds_good
ExprUnOp_bounds ExprBinOp_bounds ExprUnOpFEToWire_bounds ExprUnOpFEToZ_bounds ExprUnOpWireToFE_bounds Expr9Op_bounds Expr4Op_bounds] in H1;
destruct_head' ZBounds.bounds;
@@ -534,12 +596,12 @@ Ltac t_correct_and_bounded ropZ_sig Hbounds H0 H1 args :=
destruct_head' and;
Z.ltb_to_lt;
change WordW.wordWToZ with word64ToZ in *;
- cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd];
+ cbv [Tuple.map HList.hlist Tuple.on_tuple Tuple.from_list Tuple.from_list' Tuple.to_list Tuple.to_list' List.map HList.hlist' fst snd fe5211_32WToZ HList.hlistP HList.hlistP'];
+ cbv [WordW.bit_width BitSize64.bit_width Z.of_nat Pos.of_succ_nat Pos.succ] in *;
repeat split; unfold_is_bounded;
Z.ltb_to_lt;
try omega; try reflexivity.
-
Ltac rexpr_correct :=
let ropW' := fresh in
let ropZ_sig := fresh in
@@ -555,9 +617,13 @@ Ltac rexpr_correct :=
Notation rword_of_Z rexprZ_sig := (proj1_sig rexprZ_sig) (only parsing).
Notation compute_bounds opW bounds
- := (ApplyInterpedAll (Interp (@ZBounds.interp_op) opW) bounds)
+ := (Interp (@ZBounds.interp_op) opW bounds)
(only parsing).
+Notation rexpr_wfT e := (Wf.Wf e) (only parsing).
+
+Ltac prove_rexpr_wfT
+ := reflect_Wf Equality.base_type_eq_semidec_is_dec Equality.op_beq_bl.
Module Export PrettyPrinting.
(* We add [enlargen] to force [bounds_on] to be in [Type] in 8.4 and
@@ -569,23 +635,21 @@ Module Export PrettyPrinting.
Inductive result := yes | no | borked.
Definition ZBounds_to_bounds_on
- := fun t : base_type
- => match t return ZBounds.interp_base_type t -> match t with TZ => bounds_on end with
- | TZ => fun x => match x with
- | Some {| Bounds.lower := l ; Bounds.upper := u |}
- => in_range l u
- | None
- => overflow
- end
+ := fun (t : base_type) (x : ZBounds.interp_base_type t)
+ => match x with
+ | Some {| Bounds.lower := l ; Bounds.upper := u |}
+ => in_range l u
+ | None
+ => overflow
end.
- Fixpoint does_it_overflow {t} : interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result
- := match t return interp_flat_type (fun t => match t with TZ => bounds_on end) t -> result with
- | Tbase TZ => fun v => match v with
- | overflow => yes
- | in_range _ _ => no
- | enlargen _ => borked
- end
+ Fixpoint does_it_overflow {t} : interp_flat_type (fun t : base_type => bounds_on) t -> result
+ := match t return interp_flat_type _ t -> result with
+ | Tbase _ => fun v => match v with
+ | overflow => yes
+ | in_range _ _ => no
+ | enlargen _ => borked
+ end
| Unit => fun _ => no
| Prod x y => fun v => match @does_it_overflow _ (fst v), @does_it_overflow _ (snd v) with
| no, no => no
diff --git a/src/SpecificGen/GF5211_32Reflective/Common9_4Op.v b/src/SpecificGen/GF5211_32Reflective/Common9_4Op.v
index da61302b4..c3878caee 100644
--- a/src/SpecificGen/GF5211_32Reflective/Common9_4Op.v
+++ b/src/SpecificGen/GF5211_32Reflective/Common9_4Op.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -42,8 +41,8 @@ Lemma Expr9_4Op_correct_and_bounded
let (Hx7, Hx8) := (eta_and Hx78) in
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -80,29 +79,24 @@ Lemma Expr9_4Op_correct_and_bounded
let args := op9_args_to_bounded x012345678 Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8 in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => op9_4_bounds_good bounds = true
| None => False
end)
: op9_4_correct_and_bounded ropW op.
Proof.
- intros x0 x1 x2 x3 x4 x5 x6 x7 x8.
- intros Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8.
- pose x0 as x0'.
- pose x1 as x1'.
- pose x2 as x2'.
- pose x3 as x3'.
- pose x4 as x4'.
- pose x5 as x5'.
- pose x6 as x6'.
- pose x7 as x7'.
- pose x8 as x8'.
- hnf in x0, x1, x2, x3, x4, x5, x6, x7, x8; destruct_head' prod.
- specialize (H0 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ intros xs Hxs.
+ pose xs as xs'.
+ compute in xs.
+ destruct_head' prod.
+ cbv [Tuple.map Tuple.on_tuple Tuple.to_list Tuple.to_list' fst snd List.map Tuple.from_list Tuple.from_list' HList.hlistP HList.hlistP'] in Hxs.
+ pose Hxs as Hxs'.
+ destruct Hxs as [ [ [ [ [ [ [ [ Hx0 Hx1 ] Hx2 ] Hx3 ] Hx4 ] Hx5 ] Hx6 ] Hx7 ] Hx8 ].
+ specialize (H0 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- specialize (H1 (x0', x1', x2', x3', x4', x5', x6', x7', x8')
+ specialize (H1 xs'
(conj Hx0 (conj Hx1 (conj Hx2 (conj Hx3 (conj Hx4 (conj Hx5 (conj Hx6 (conj Hx7 Hx8))))))))).
- Time let args := constr:(op9_args_to_bounded (x0', x1', x2', x3', x4', x5', x6', x7', x8') Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
+ Time let args := constr:(op9_args_to_bounded xs' Hx0 Hx1 Hx2 Hx3 Hx4 Hx5 Hx6 Hx7 Hx8) in
admit; t_correct_and_bounded ropZ_sig Hbounds H0 H1 args. (* On 8.6beta1, with ~2 GB RAM, Finished transaction in 46.56 secs (46.372u,0.14s) (successful) *)
Admitted. (*Time Qed. (* On 8.6beta1, with ~4.3 GB RAM, Finished transaction in 67.652 secs (66.932u,0.64s) (successful) *)*)
diff --git a/src/SpecificGen/GF5211_32Reflective/CommonBinOp.v b/src/SpecificGen/GF5211_32Reflective/CommonBinOp.v
index 6d4f73920..f54be4d6a 100644
--- a/src/SpecificGen/GF5211_32Reflective/CommonBinOp.v
+++ b/src/SpecificGen/GF5211_32Reflective/CommonBinOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -18,8 +17,8 @@ Lemma ExprBinOp_correct_and_bounded
let Hy := let (Hx, Hy) := Hxy in Hy in
let args := binop_args_to_bounded xy Hx Hy in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -33,18 +32,19 @@ Lemma ExprBinOp_correct_and_bounded
let args := binop_args_to_bounded (fst xy, snd xy) Hx Hy in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => binop_bounds_good bounds = true
| None => False
end)
: binop_correct_and_bounded ropW op.
Proof.
- intros x y Hx Hy.
- pose x as x'; pose y as y'.
- hnf in x, y; destruct_head' prod.
- specialize (H0 (x', y') (conj Hx Hy)).
- specialize (H1 (x', y') (conj Hx Hy)).
- let args := constr:(binop_args_to_bounded (x', y') Hx Hy) in
+ intros xy HxHy.
+ pose xy as xy'.
+ compute in xy; destruct_head' prod.
+ specialize (H0 xy' HxHy).
+ specialize (H1 xy' HxHy).
+ destruct HxHy as [Hx Hy].
+ let args := constr:(binop_args_to_bounded xy' Hx Hy) in
t_correct_and_bounded ropZ_sig Hbounds H0 H1 args.
Qed.
diff --git a/src/SpecificGen/GF5211_32Reflective/CommonUnOp.v b/src/SpecificGen/GF5211_32Reflective/CommonUnOp.v
index d8bc7dcfa..c4fa848f6 100644
--- a/src/SpecificGen/GF5211_32Reflective/CommonUnOp.v
+++ b/src/SpecificGen/GF5211_32Reflective/CommonUnOp.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOp_correct_and_bounded
(Hx : is_bounded (fe5211_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOp_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unop_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToWire.v b/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToWire.v
index 91469dc14..433609622 100644
--- a/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToWire.v
+++ b/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToWire.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
(Hx : is_bounded (fe5211_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToWire_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToWire_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToZ.v b/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToZ.v
index 68389da47..6b48722c2 100644
--- a/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToZ.v
+++ b/src/SpecificGen/GF5211_32Reflective/CommonUnOpFEToZ.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
(Hx : is_bounded (fe5211_32WToZ x) = true),
let args := unop_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpFEToZ_correct_and_bounded
let args := unop_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopFEToZ_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF5211_32Reflective/CommonUnOpWireToFE.v b/src/SpecificGen/GF5211_32Reflective/CommonUnOpWireToFE.v
index 48b8c853a..324729d2c 100644
--- a/src/SpecificGen/GF5211_32Reflective/CommonUnOpWireToFE.v
+++ b/src/SpecificGen/GF5211_32Reflective/CommonUnOpWireToFE.v
@@ -3,7 +3,6 @@ Require Import Crypto.SpecificGen.GF5211_32BoundedCommon.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Util.Tactics.
Local Opaque Interp.
@@ -15,8 +14,8 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
(Hx : wire_digits_is_bounded (wire_digitsWToZ x) = true),
let args := unopWireToFE_args_to_bounded x Hx in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@BoundedWordW.interp_op) ropW)
- (LiftOption.to' (Some args)))
+ (Interp (@BoundedWordW.interp_op) ropW
+ (LiftOption.to' (Some args)))
with
| Some _ => True
| None => False
@@ -27,7 +26,7 @@ Lemma ExprUnOpWireToFE_correct_and_bounded
let args := unopWireToFE_args_to_bounded x Hx in
let x' := SmartVarfMap (fun _ : base_type => BoundedWordW.BoundedWordToBounds) args in
match LiftOption.of'
- (ApplyInterpedAll (Interp (@ZBounds.interp_op) ropW) (LiftOption.to' (Some x')))
+ (Interp (@ZBounds.interp_op) ropW (LiftOption.to' (Some x')))
with
| Some bounds => unopWireToFE_bounds_good bounds = true
| None => False
diff --git a/src/SpecificGen/GF5211_32Reflective/Reified/AddCoordinates.v b/src/SpecificGen/GF5211_32Reflective/Reified/AddCoordinates.v
index 90f391ba5..e85a6f2cd 100644
--- a/src/SpecificGen/GF5211_32Reflective/Reified/AddCoordinates.v
+++ b/src/SpecificGen/GF5211_32Reflective/Reified/AddCoordinates.v
@@ -7,7 +7,6 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.ExprInversion.
Require Import Crypto.Reflection.Relations.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
@@ -17,7 +16,10 @@ Require Export Crypto.Reflection.Z.Syntax.
Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.CompleteEdwardsCurve.ExtendedCoordinates.
+Require Import Crypto.SpecificGen.GF5211_32Reflective.Common.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Mul.
@@ -33,24 +35,28 @@ Require Import Bedrock.Word.
Definition radd_coordinatesZ' var twice_d P1 P2
:= @Extended.add_coordinates_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
twice_d _
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
P1 P2.
+Local Notation eta x := (fst x, snd x).
+
Definition radd_coordinatesZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
- => radd_coordinatesZ'
- var (Return twice_d)
- (Return P10, Return P11, Return P12, Return P13)
- (Return P20, Return P21, Return P22, Return P23))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun twice_d_P1_P2 : interp_flat_type _ (_ * ((_ * _ * _ * _) * (_ * _ * _ * _)))
+ => let '(twice_d, ((P10, P11, P12, P13), (P20, P21, P22, P23)))
+ := twice_d_P1_P2 in
+ radd_coordinatesZ'
+ var (SmartVarf twice_d)
+ (SmartVarf P10, SmartVarf P11, SmartVarf P12, SmartVarf P13)
+ (SmartVarf P20, SmartVarf P21, SmartVarf P22, SmartVarf P23)))).
Definition add_coordinates
:= fun twice_d P10 P11 P12 P13 P20 P21 P22 P23
@@ -59,70 +65,60 @@ Definition add_coordinates
twice_d (P10, P11, P12, P13) (P20, P21, P22, P23).
Definition uncurried_add_coordinates
- := apply9_nd
- (@uncurry_unop_fe5211_32)
- add_coordinates.
+ := fun twice_d_P1_P2
+ => let twice_d := fst twice_d_P1_P2 in
+ let (P1, P2) := eta (snd twice_d_P1_P2) in
+ @Extended.add_coordinates
+ _ add sub mul
+ twice_d P1 P2.
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
let H := fresh in
pose k as k';
assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
- repeat (unfold interpf_step at 1; change k with k' at 1);
+ repeat (unfold k'; change k with k'; unfold interpf_step);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF5211_32.fe5211_32 -> GF5211_32.fe5211_32 -> GF5211_32.fe5211_32)
- (x' y' : GF5211_32.fe5211_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe5211_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
+Lemma radd_coordinatesZ_sigP' : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe5211_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF5211_32.fe5211_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe5211_32 Apply' interp fst snd].
- rewrite (invert_Abs_Some (e:=f) eq_refl).
+ cbv [radd_coordinatesZ''].
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type] in x.
+ destruct x as [twice_d [ [ [ [P10_ P11_] P12_] P13_] [ [ [P20_ P21_] P22_] P23_] ] ].
repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
+ | [ H : prod _ _ |- _ ] => let H0 := fresh H in let H1 := fresh H in destruct H as [H0 H1]
end.
- reflexivity.
-Qed.
-
-Lemma radd_coordinatesZ_sigP : rexpr_sigP Expr9_4OpT uncurried_add_coordinates radd_coordinatesZ''.
-Proof.
- cbv [radd_coordinatesZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT radd_coordinatesZ'' uncurried_add_coordinates uncurry_unop_fe5211_32 SmartAbs radd_coordinatesZ' exprArg Extended.add_coordinates_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe5211_32 add_coordinates].
- intros.
- unfold invert_Return at 13 14 15 16.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [radd_coordinatesZ' add_coordinates Extended.add_coordinates_gen uncurried_add_coordinates SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -132,48 +128,56 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 13 14 15; unfold interpf_step.
- cbv beta iota delta [Extended.add_coordinates].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition radd_coordinatesZ_sig : rexpr_9_4op_sig add_coordinates.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv beta iota delta [Extended.add_coordinates interp_flat_type interp_base_type GF5211_32.fe5211_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma radd_coordinatesZ_sigP : rexpr_sigP _ uncurried_add_coordinates radd_coordinatesZ''.
Proof.
- eexists.
- apply radd_coordinatesZ_sigP.
-Defined.
+ exact radd_coordinatesZ_sigP'.
+Qed.
+Definition radd_coordinatesZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) radd_coordinatesZ'' radd_coordinatesZ_sigP.
+
+Definition radd_coordinates_input_bounds
+ := (ExprUnOp_bounds, ((ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition radd_coordinatesW := Eval vm_compute in rword_of_Z radd_coordinatesZ_sig.
Lemma radd_coordinatesW_correct_and_bounded_gen : correct_and_bounded_genT radd_coordinatesW radd_coordinatesZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW Expr9Op_bounds.
+Definition radd_coordinates_output_bounds := Eval vm_compute in compute_bounds radd_coordinatesW radd_coordinates_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition radd_coordinatesW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- radd_coordinatesW add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
+ radd_coordinatesW uncurried_add_coordinates radd_coordinatesZ_sig radd_coordinatesW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW Expr9Op_bounds).
-Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW Expr9Op_bounds).
+Compute ("Add_Coordinates", compute_bounds_for_display radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows? ", sanity_compute radd_coordinatesW radd_coordinates_input_bounds).
+Compute ("Add_Coordinates overflows (error if it does)? ", sanity_check radd_coordinatesW radd_coordinates_input_bounds).
diff --git a/src/SpecificGen/GF5211_32Reflective/Reified/LadderStep.v b/src/SpecificGen/GF5211_32Reflective/Reified/LadderStep.v
index 16c0173a0..4e7a5f9b3 100644
--- a/src/SpecificGen/GF5211_32Reflective/Reified/LadderStep.v
+++ b/src/SpecificGen/GF5211_32Reflective/Reified/LadderStep.v
@@ -7,8 +7,9 @@ Require Import Crypto.Reflection.Syntax.
Require Import Crypto.Reflection.SmartMap.
Require Import Crypto.Reflection.Relations.
Require Import Crypto.Reflection.ExprInversion.
-Require Import Crypto.Reflection.Application.
Require Import Crypto.Reflection.Linearize.
+Require Import Crypto.Reflection.Eta.
+Require Import Crypto.Reflection.EtaInterp.
Require Import Crypto.Reflection.Z.Interpretations64.
Require Crypto.Reflection.Z.Interpretations64.Relations.
Require Import Crypto.Reflection.Z.Interpretations64.RelationsCombinations.
@@ -18,6 +19,7 @@ Require Import Crypto.Reflection.InterpWfRel.
Require Import Crypto.Reflection.LinearizeInterp.
Require Import Crypto.Reflection.WfReflective.
Require Import Crypto.Spec.MxDH.
+Require Import Crypto.SpecificGen.GF5211_32Reflective.Common.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Add.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Sub.
Require Import Crypto.SpecificGen.GF5211_32Reflective.Reified.Mul.
@@ -30,50 +32,80 @@ Require Import Crypto.Util.Tactics.
Require Import Crypto.Util.Notations.
Require Import Bedrock.Word.
-(* XXX FIXME: Remove dummy code *)
-Definition rladderstepZ' var (T:=_) (dummy0 dummy1 dummy2 a24 x0 : T) P1 P2
+Definition rladderstepZ' var (T:=_) (a24 x0 : T) P1 P2
:= @MxDH.ladderstep_gen
_
- (fun x y => ApplyBinOp (proj1_sig raddZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rsubZ_sig var) x y)
- (fun x y => ApplyBinOp (proj1_sig rmulZ_sig var) x y)
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig raddZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rsubZ_sig var)))
+ (fun x y => LetIn (Pair x y) (invert_Abs (proj1_sig rmulZ_sig var)))
a24
_
- (fun x y z w => (invert_Return x, invert_Return y, invert_Return z, invert_Return w)%expr)
- (fun v f => LetIn (invert_Return v)
- (fun k => f (Return (SmartVarf k))))
+ (fun x y z w => (x, y, z, w)%expr)
+ (fun v f => LetIn v
+ (fun k => f (SmartVarf k)))
x0
P1 P2.
Definition rladderstepZ'' : Syntax.Expr _ _ _
- := Linearize (fun var
- => apply9
- (fun A B => SmartAbs (A := A) (B := B))
- (fun dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21
- => rladderstepZ'
- var (Return dummy0) (Return dummy1) (Return dummy2)
- (Return a24) (Return x0)
- (Return P10, Return P11)
- (Return P20, Return P21))).
+ := Linearize
+ (ExprEta
+ (fun var
+ => Abs (fun a24_x0_P1_P2 : interp_flat_type _ (_ * _ * ((_ * _) * (_ * _)))
+ => let '(a24, x0, ((P10, P11), (P20, P21)))
+ := a24_x0_P1_P2 in
+ rladderstepZ'
+ var (SmartVarf a24) (SmartVarf x0)
+ (SmartVarf P10, SmartVarf P11)
+ (SmartVarf P20, SmartVarf P21)))).
-Definition ladderstep (T := _)
- := fun (dummy0 dummy1 dummy2 a24 x0 P10 P11 P20 P21 : T)
- => @MxDH.ladderstep_other_assoc
- _ add sub mul
- a24 x0 (P10, P11) (P20, P21).
+Local Notation eta x := (fst x, snd x).
+
+Definition ladderstep_other_assoc {F Fadd Fsub Fmul} a24 (X1:F) (P1 P2:F*F) : F*F*F*F :=
+ Eval cbv beta delta [MxDH.ladderstep_gen] in
+ @MxDH.ladderstep_gen
+ F Fadd Fsub Fmul a24
+ (F*F*F*F)
+ (fun X3 Y3 Z3 T3 => (X3, Y3, Z3, T3))
+ (fun x f => dlet y := x in f y)
+ X1 P1 P2.
Definition uncurried_ladderstep
- := apply9_nd
- (@uncurry_unop_fe5211_32)
- ladderstep.
+ := fun (a24_x0_P1_P2 : _ * _ * ((_ * _) * (_ * _)))
+ => let a24 := fst (fst a24_x0_P1_P2) in
+ let x0 := snd (fst a24_x0_P1_P2) in
+ let '(P1, P2) := eta (snd a24_x0_P1_P2) in
+ let '((P10, P11), (P20, P21)) := (eta P1, eta P2) in
+ @ladderstep_other_assoc
+ _ add sub mul
+ a24 x0 (P10, P11) (P20, P21).
+Local Notation rexpr_sigPf T uncurried_op rexprZ x :=
+ (Interp interp_op (t:=T) rexprZ x = uncurried_op x)
+ (only parsing).
Local Notation rexpr_sigP T uncurried_op rexprZ :=
- (interp_type_gen_rel_pointwise (fun _ => Logic.eq) (Interp interp_op (t:=T) rexprZ) uncurried_op)
+ (forall x, rexpr_sigPf T uncurried_op rexprZ x)
(only parsing).
Local Notation rexpr_sig T uncurried_op :=
{ rexprZ | rexpr_sigP T uncurried_op rexprZ }
(only parsing).
+Local Ltac fold_interpf' :=
+ let k := (eval unfold interpf, interpf_step in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k'.
+
+Local Ltac fold_interpf :=
+ let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
+ let k' := fresh in
+ let H := fresh in
+ pose k as k';
+ assert (H : @interpf base_type interp_base_type op interp_op = k') by reflexivity;
+ change k with k'; clearbody k'; subst k';
+ fold_interpf'.
+
Local Ltac repeat_step_interpf :=
let k := (eval unfold interpf in (@interpf base_type interp_base_type op interp_op)) in
let k' := fresh in
@@ -83,51 +115,14 @@ Local Ltac repeat_step_interpf :=
repeat (unfold interpf_step at 1; change k with k' at 1);
clearbody k'; subst k'.
-Lemma interp_helper
- (f : Syntax.Expr base_type op ExprBinOpT)
- (x y : exprArg interp_base_type)
- (f' : GF5211_32.fe5211_32 -> GF5211_32.fe5211_32 -> GF5211_32.fe5211_32)
- (x' y' : GF5211_32.fe5211_32)
- (H : interp_type_gen_rel_pointwise
- (fun _ => Logic.eq)
- (Interp interp_op f) (uncurry_binop_fe5211_32 f'))
- (Hx : interpf interp_op (invert_Return x) = x')
- (Hy : interpf interp_op (invert_Return y) = y')
- : interpf interp_op (invert_Return (ApplyBinOp (f interp_base_type) x y)) = f' x' y'.
-Proof.
- cbv [interp_type_gen_rel_pointwise ExprBinOpT uncurry_binop_fe5211_32 interp_flat_type] in H.
- simpl @interp_base_type in *.
- cbv [GF5211_32.fe5211_32] in x', y'.
- destruct_head' prod.
- rewrite <- H; clear H.
- cbv [ExprArgT] in *; simpl in *.
- rewrite Hx, Hy; clear Hx Hy.
- unfold Let_In; simpl.
- cbv [Interp].
- simpl @interp_type.
- change (fun t => interp_base_type t) with interp_base_type in *.
- generalize (f interp_base_type); clear f; intro f.
- cbv [Apply length_fe5211_32 Apply' interp fst snd].
- let f := match goal with f : expr _ _ _ |- _ => f end in
- rewrite (invert_Abs_Some (e:=f) eq_refl).
- repeat match goal with
- | [ |- appcontext[invert_Abs ?f ?x] ]
- => generalize (invert_Abs f x); clear f;
- let f' := fresh "f" in
- intro f';
- first [ rewrite (invert_Abs_Some (e:=f') eq_refl)
- | rewrite (invert_Return_Some (e:=f') eq_refl) at 2 ]
- end.
- reflexivity.
-Qed.
-
-Lemma rladderstepZ_sigP : rexpr_sigP Expr9_4OpT uncurried_ladderstep rladderstepZ''.
+Lemma rladderstepZ_sigP' : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
cbv [rladderstepZ''].
- etransitivity; [ apply InterpLinearize | ].
- cbv beta iota delta [apply9 apply9_nd interp_type_gen_rel_pointwise Expr9_4OpT SmartArrow ExprArgT rladderstepZ'' uncurried_ladderstep uncurry_unop_fe5211_32 SmartAbs rladderstepZ' exprArg MxDH.ladderstep_gen Interp interp unop_make_args SmartVarf smart_interp_flat_map length_fe5211_32 ladderstep].
- intros; cbv beta zeta.
- unfold invert_Return at 14 15 16 17.
+ intro x; rewrite InterpLinearize, InterpExprEta.
+ cbv [domain interp_flat_type interp_base_type] in x.
+ destruct_head' prod.
+ cbv [invert_Abs domain codomain Interp interp SmartVarf smart_interp_flat_map fst snd].
+ cbv [rladderstepZ' MxDH.ladderstep_gen uncurried_ladderstep SmartVarf smart_interp_flat_map]; simpl @fst; simpl @snd.
repeat match goal with
| [ |- appcontext[@proj1_sig ?A ?B ?v] ]
=> let k := fresh "f" in
@@ -137,48 +132,58 @@ Proof.
set (k' := @proj1_sig A B k);
pose proof (proj2_sig k) as H;
change (proj1_sig k) with k' in H;
- clearbody k'; clear k
+ clearbody k'; clear k;
+ cbv beta in *
end.
- unfold interpf; repeat_step_interpf.
- unfold interpf at 14 15 16; unfold interpf_step.
- cbv beta iota delta [MxDH.ladderstep_other_assoc].
- repeat match goal with
- | [ |- (dlet x := ?y in @?z x) = (let x' := ?y' in @?z' x') ]
- => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
- (_ : y = y')
- (_ : forall x, z x = z' x));
- cbv beta; intros
- end;
- repeat match goal with
- | [ |- interpf interp_op (invert_Return (ApplyBinOp _ _ _)) = _ ]
- => apply interp_helper; [ assumption | | ]
- | [ |- interpf interp_op (invert_Return (Return (_, _)%expr)) = (_, _) ]
- => vm_compute; reflexivity
- | [ |- (_, _) = (_, _) ]
- => reflexivity
- | _ => simpl; rewrite <- !surjective_pairing; reflexivity
- end.
-Time Qed.
-
-Definition rladderstepZ_sig : rexpr_9_4op_sig ladderstep.
+ cbv [Interp Curry.curry2] in *.
+ unfold interpf, interpf_step; fold_interpf.
+ cbv [ladderstep_other_assoc interp_flat_type GF5211_32.fe5211_32].
+ Time
+ abstract (
+ repeat match goal with
+ | [ |- (dlet x := ?y in @?z x) = (dlet x' := ?y' in @?z' x') ]
+ => refine ((fun pf0 pf1 => @Proper_Let_In_nd_changebody _ _ Logic.eq _ y y' pf0 z z' pf1)
+ (_ : y = y')
+ (_ : forall x, z x = z' x));
+ cbv beta; intros;
+ [ cbv [Let_In Common.ExprBinOpT] | ]
+ end;
+ repeat match goal with
+ | _ => rewrite !interpf_invert_Abs
+ | _ => rewrite_hyp !*
+ | _ => progress cbv [interp_base_type]
+ | [ |- ?x = ?x ] => reflexivity
+ | _ => rewrite <- !surjective_pairing
+ end
+ ).
+Time Defined.
+Lemma rladderstepZ_sigP : rexpr_sigP _ uncurried_ladderstep rladderstepZ''.
Proof.
- eexists.
- apply rladderstepZ_sigP.
-Defined.
+ exact rladderstepZ_sigP'.
+Qed.
+Definition rladderstepZ_sig
+ := exist (fun v => rexpr_sigP _ _ v) rladderstepZ'' rladderstepZ_sigP.
+
+Definition rladderstep_input_bounds
+ := (ExprUnOp_bounds, ExprUnOp_bounds,
+ ((ExprUnOp_bounds, ExprUnOp_bounds),
+ (ExprUnOp_bounds, ExprUnOp_bounds))).
Time Definition rladderstepW := Eval vm_compute in rword_of_Z rladderstepZ_sig.
Lemma rladderstepW_correct_and_bounded_gen : correct_and_bounded_genT rladderstepW rladderstepZ_sig.
Proof. Time rexpr_correct. Time Qed.
-Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW Expr9Op_bounds.
+Definition rladderstep_output_bounds := Eval vm_compute in compute_bounds rladderstepW rladderstep_input_bounds.
Local Obligation Tactic := intros; vm_compute; constructor.
+(*
Program Definition rladderstepW_correct_and_bounded
:= Expr9_4Op_correct_and_bounded
- rladderstepW ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
+ rladderstepW uncurried_ladderstep rladderstepZ_sig rladderstepW_correct_and_bounded_gen
_ _.
+ *)
Local Open Scope string_scope.
-Compute ("Ladderstep", compute_bounds_for_display rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows? ", sanity_compute rladderstepW Expr9Op_bounds).
-Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW Expr9Op_bounds).
+Compute ("Ladderstep", compute_bounds_for_display rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows? ", sanity_compute rladderstepW rladderstep_input_bounds).
+Compute ("Ladderstep overflows (error if it does)? ", sanity_check rladderstepW rladderstep_input_bounds).
diff --git a/src/SpecificGen/GF5211_32Reflective/Reified/PreFreeze.v b/src/SpecificGen/GF5211_32Reflective/Reified/PreFreeze.v
index 4788f9f1a..5cf7ea98a 100644
--- a/src/SpecificGen/GF5211_32Reflective/Reified/PreFreeze.v
+++ b/src/SpecificGen/GF5211_32Reflective/Reified/PreFreeze.v
@@ -1,6 +1,6 @@
Require Import Crypto.SpecificGen.GF5211_32Reflective.CommonUnOp.
-Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. cbv [prefreeze GF5211_32.prefreeze]. reify_sig. Defined.
+Definition rprefreezeZ_sig : rexpr_unop_sig prefreeze. Proof. reify_sig. Defined.
Definition rprefreezeW := Eval vm_compute in rword_of_Z rprefreezeZ_sig.
Lemma rprefreezeW_correct_and_bounded_gen : correct_and_bounded_genT rprefreezeW rprefreezeZ_sig.
Proof. rexpr_correct. Qed.
diff --git a/src/SpecificGen/GF5211_32ReflectiveAddCoordinates.v b/src/SpecificGen/GF5211_32ReflectiveAddCoordinates.v
index ee7bbb2e2..8105fd507 100644
--- a/src/SpecificGen/GF5211_32ReflectiveAddCoordinates.v
+++ b/src/SpecificGen/GF5211_32ReflectiveAddCoordinates.v
@@ -32,7 +32,7 @@ Import ListNotations.
Require Import Coq.ZArith.ZArith Coq.ZArith.Zpower Coq.ZArith.ZArith Coq.ZArith.Znumtheory.
Local Open Scope Z.
-Time Definition radd_coordinates : Expr9_4Op := Eval vm_compute in radd_coordinatesW.
+Time Definition radd_coordinates : Expr _ := Eval vm_compute in radd_coordinatesW.
Declare Reduction asm_interp_add_coordinates
:= cbv beta iota delta
@@ -57,7 +57,7 @@ Ltac asm_interp_add_coordinates
mapf_interp_flat_type WordW.interp_base_type word64ize
Interp interp interp_flat_type interpf interp_flat_type fst snd].
-
+(*
Time Definition interp_radd_coordinates : SpecificGen.GF5211_32BoundedCommon.fe5211_32W
-> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
-> SpecificGen.GF5211_32BoundedCommon.fe5211_32W
@@ -74,3 +74,4 @@ Time Definition interp_radd_coordinates_correct : interp_radd_coordinates = inte
Lemma radd_coordinates_correct_and_bounded : op9_4_correct_and_bounded radd_coordinates add_coordinates.
Proof. exact_no_check radd_coordinatesW_correct_and_bounded. Time Qed.
+*)