aboutsummaryrefslogtreecommitdiff
path: root/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v')
-rw-r--r--src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v62
1 files changed, 56 insertions, 6 deletions
diff --git a/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v b/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
index 1f82cb9f8..f132eb92a 100644
--- a/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
+++ b/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
@@ -22,6 +22,8 @@ Require Import Crypto.Compilers.Z.Bounds.Interpretation.
Require Import Crypto.Compilers.Z.Bounds.Relax.
Require Import Crypto.Compilers.Reify.
Require Import Crypto.Compilers.Z.Reify.
+Require Import Crypto.Compilers.InterpSideConditions.
+Require Import Crypto.Compilers.Z.InterpSideConditions.
Require Import Crypto.Compilers.Z.Bounds.Pipeline.Definition.
Require Import Crypto.Util.Tactics.Head.
Require Import Crypto.Util.Tactics.SubstLet.
@@ -123,6 +125,45 @@ Ltac unify_abstract_cbv_interp_rhs_reflexivity :=
unify LHS RHS'; abstract exact_no_check (eq_refl RHS')
end.
+(** *** Boundedness Lemma Side Conditions *)
+(** The tactic [handle_boundedness_side_condition] unfolds relevant
+ identifiers in the side-condition of the boundedness lemma. It
+ then calls [boundedness_side_condition_solver], which can be
+ overridden. *)
+(** The tactic [boundedness_side_condition_solver] attempts to solve
+ the algebraic side conditions of the boundedness lemma; it leaves
+ them over if it cannot solve them. *)
+Ltac boundedness_side_condition_solver :=
+ repeat match goal with
+ | [ |- _ /\ _ ] => apply conj
+ | [ |- ?x = ?x ] => reflexivity
+ end;
+ try abstract ring.
+Ltac handle_boundedness_side_condition :=
+ (** TODO: This next bit, with repeat intros [? ?], could be done
+ with a single [apply], if we make the right lemma. We should
+ write that lemma. *)
+ cbv [PointedProp.to_prop Syntax.interp_flat_type Syntax.interp_base_type Syntax.domain Syntax.codomain];
+ repeat match goal with
+ | [ |- forall x : _ * _, _ ]
+ => let a := fresh in let b := fresh in intros [a b]; revert a b
+ | [ |- forall x, _ ]
+ => let x := fresh "x" in intro x
+ end;
+ cbv [id
+ fst snd
+ InterpSideConditions Compilers.InterpSideConditions.InterpSideConditions interp_side_conditions interpf_side_conditions interpf_side_conditions_gen
+ Z.Syntax.Util.interped_op_side_conditions
+ ExprInversion.invert_Abs
+ Syntax.interp_op Syntax.lift_op
+ Syntax.Zinterp_op
+ SmartMap.SmartFlatTypeMapUnInterp SmartMap.SmartValf SmartMap.SmartFlatTypeMapInterp2
+ Syntax.cast_const Syntax.ZToInterp Syntax.interpToZ];
+ cbv [PointedProp.and_pointed_Prop];
+ try match goal with
+ | [ |- True ] => exact I
+ end;
+ boundedness_side_condition_solver.
(** ** Assemble the parts of Pipeline.Definition, in Gallina *)
(** In this section, we assemble [PreWfPipeline] and [PostWfPipeline],
@@ -144,6 +185,7 @@ Require Import Crypto.Compilers.Z.Syntax.Equality.
Require Import Crypto.Compilers.Z.Syntax.Util.
Require Import Crypto.Compilers.Z.Bounds.Interpretation.
Require Import Crypto.Compilers.Z.Bounds.Relax.
+Require Import Crypto.Util.PointedProp.
Require Import Crypto.Util.PartiallyReifiedProp.
Require Import Crypto.Util.Equality.
@@ -164,6 +206,7 @@ Section with_round_up_list.
{fZ}
{final_e_evar : interp_flat_type Syntax.interp_base_type (pick_type given_output_bounds)}
{e}
+ {e_pre_pkg}
{e_pkg}
(** ** reification *)
(rexpr_sig : { rexpr : Expr base_type op t | forall x, Interp Syntax.interp_op rexpr x = fZ x })
@@ -174,8 +217,10 @@ Section with_round_up_list.
(Hwf : forall var1 var2,
let P := (@reflect_wfT base_type base_type_eq_semidec_transparent op op_beq var1 var2 nil _ _ (ExprEta' e _) (ExprEta' e _)) in
trueify P = P)
+ (** ** post-wf-pre-bounds-pipeline *)
+ (Hpost_wf_pre_bounds : e_pre_pkg = PostWfPreBoundsPipeline opts e)
(** ** post-wf-pipeline *)
- (Hpost : e_pkg = PostWfPipeline _ opts e input_bounds)
+ (Hpost : e_pkg = PostWfBoundsPipeline _ opts e e_pre_pkg input_bounds)
(Hpost_correct : Some {| input_expr := e ; input_bounds := input_bounds ; output_bounds := b ; output_expr := e' |} = e_pkg)
(** ** renaming *)
(Hrenaming : e_final = e')
@@ -187,8 +232,9 @@ Section with_round_up_list.
= eq_rect _ (fun t => Expr base_type op (Arrow (pick_type input_bounds) t)) e' _ (eq_sym Hbounds_sane))
(** ** instantiation of original evar *)
(Hevar : final_e_evar = InterpEta (t:=Arrow _ _) Syntax.interp_op e_final_newtype v')
- (** ** side condition *)
- (Hv : Bounds.is_bounded_by input_bounds (cast_back_flat_const v'))
+ (** ** side conditions (boundedness) *)
+ (Hv1 : Bounds.is_bounded_by input_bounds (cast_back_flat_const v'))
+ (Hv2 : forall v, PointedProp.to_prop (InterpSideConditions e_pre_pkg v))
: Bounds.is_bounded_by given_output_bounds (fZ (cast_back_flat_const v'))
/\ cast_back_flat_const final_e_evar = fZ (cast_back_flat_const v').
Proof.
@@ -223,8 +269,8 @@ End with_round_up_list.
Ltac refine_with_pipeline_correct opts :=
lazymatch goal with
| [ |- _ /\ ?castback ?fW = ?fZ ?arg ]
- => let lem := open_constr:(@PipelineCorrect _ opts _ _ _ _ _ _ _ _ _ _ _ _) in
- simple refine (lem _ _ _ _ _ _ _ _ _ _ _ _);
+ => let lem := open_constr:(@PipelineCorrect _ opts _ _ _ _ _ _ _ _ _ _ _ _ _) in
+ simple refine (lem _ _ _ _ _ _ _ _ _ _ _ _ _ _);
subst fW fZ
end;
[ eexists
@@ -264,6 +310,8 @@ Ltac solve_side_conditions :=
unify_abstract_vm_compute_rhs_reflexivity |
(** ** reflective wf side-condition 2 *)
unify_abstract_vm_compute_rhs_reflexivity |
+ (** ** post-wf-pre-bounds-pipeline *)
+ unify_abstract_vm_compute_rhs_reflexivity |
(** ** post-wf pipeline *)
unify_abstract_vm_compute_rhs_reflexivity |
(** ** post-wf pipeline gives [Some _] *)
@@ -283,7 +331,9 @@ Ltac solve_side_conditions :=
(** ** unfolding of [interp] constants *)
unify_abstract_cbv_interp_rhs_reflexivity |
(** ** boundedness of inputs *)
- abstract handle_bounds_from_hyps ].
+ abstract handle_bounds_from_hyps |
+ (** ** boundedness side-condition *)
+ handle_boundedness_side_condition ].
(** ** The Entire Pipeline *)