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.v362
1 files changed, 0 insertions, 362 deletions
diff --git a/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v b/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
deleted file mode 100644
index 9193ea17f..000000000
--- a/src/Compilers/Z/Bounds/Pipeline/ReflectiveTactics.v
+++ /dev/null
@@ -1,362 +0,0 @@
-(** * Reflective Pipeline: Tactics that execute the pipeline *)
-(** N.B. This file should not need to be changed in normal
- modifications of the reflective transformations; to modify the
- transformations performed in the reflective pipeline; see
- Pipeline/Definition.v. If the input format of the pre-reflective
- goal changes, prefer adding complexity to Pipeline/Glue.v to
- transform the goal and hypotheses into a uniform syntax to
- modifying this file. This file will need to be modified if you
- perform heavy changes in the shape of the generic or ℤ-specific
- reflective machinery itself, or if you find bugs or slowness. *)
-(** ** Preamble *)
-Require Import Coq.ZArith.ZArith.
-Require Import Crypto.Compilers.Syntax.
-Require Import Crypto.Compilers.Intros.
-Require Import Crypto.Compilers.Wf.
-Require Import Crypto.Compilers.WfReflective.
-Require Import Crypto.Compilers.RenameBinders.
-Require Import Crypto.Compilers.Eta.
-Require Import Crypto.Compilers.EtaInterp.
-Require Import Crypto.Compilers.Z.Syntax.
-Require Import Crypto.Compilers.Z.Syntax.Util.
-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.
-Require Import Crypto.Util.Tactics.UnfoldArg.
-Require Import Crypto.Util.Tactics.UnifyAbstractReflexivity.
-Require Import Crypto.Util.FixedWordSizes.
-Require Import Crypto.Util.Option.
-Require Import bbv.WordScope.
-
-(** The final tactic in this file, [do_reflective_pipeline], takes a
- goal of the form
-<<
-@Bounds.is_bounded_by (codomain T) bounds (fZ (cast_back_flat_const v))
- /\ cast_back_flat_const fW = fZ (cast_back_flat_const v)
->>
-
- where [fW] must be a context definition which is a single evar,
- and all other terms must be evar-free. It fully solves the goal,
- instantiating [fW] with an appropriately-unfolded
- (reflection-definition-free) version of [fZ (cast_back_flat_const
- v)] which has been transformed by the reflective pipeline. *)
-
-Module Export Exports.
- Export Crypto.Compilers.Reify. (* export for the instances for recursing under binders *)
- Export Crypto.Compilers.Z.Reify. (* export for the tactic redefinitions *)
- Export Crypto.Compilers.Z.Bounds.Pipeline.Definition.Exports.
-End Exports.
-
-(** ** Reification *)
-(** The [do_reify] tactic handles goals of the form
-<<
-forall x, Interp _ ?e x = F
->>
- by reifying [F]. *)
-Ltac do_reify :=
- unfold_second_arg Tuple.tuple;
- unfold_second_arg Tuple.tuple';
- cbv beta iota delta [Tuple.tuple Tuple.tuple'] in *;
- cbv beta iota delta [Syntax.interp_flat_type Syntax.interp_base_type];
- reify_context_variables;
- Reify_rhs; reflexivity.
-(** ** Input Boundedness Side-Conditions *)
-(** The tactic [handle_bounds_from_hyps] handles goals of the form
-<<
-Bounds.is_bounded_by (_, _, ..., _) _
->>
- by splitting them apart and looking in the context for hypotheses
- that prove the bounds. *)
-Ltac handle_bounds_from_hyps :=
- repeat match goal with
- | _ => assumption
- | [ |- cast_back_flat_const _ = cast_back_flat_const _ ] => reflexivity
- | [ |- _ /\ _ ] => split
- | [ |- Bounds.is_bounded_by (_, _) _ ] => split
- end.
-(** ** Unfolding [Interp] *)
-(** The reduction strategies [interp_red], [extra_interp_red], and
- [constant_simplification] (the latter two defined in
- Pipeline/Definition.v) define the constants that get unfolded
- before instantiating the original evar with [Interp _
- vm_computed_reified_expression arguments]. *)
-Declare Reduction interp_red
- := cbv [fst snd
- Interp (*InterpEta interp_op*) interp interp_eta interpf interpf_step
- interp_flat_type_eta interp_flat_type_eta_gen interp_flat_type
- interp_base_type interp_op
- SmartMap.SmartFlatTypeMap SmartMap.SmartFlatTypeMapUnInterp SmartMap.SmartFlatTypeMapInterp2
- SmartMap.smart_interp_flat_map
- codomain domain
- lift_op Zinterp_op cast_const
- ZToInterp interpToZ
- ].
-
-(** ** Solving Side-Conditions of Equality *)
-(** This section defines a number of different ways to solve goals of
- the form [LHS = RHS] where [LHS] may contain evars and [RHS] must
- not contain evars. Most tactics use [abstract] to reduce the load
- on [Defined] and to catch looping behavior early. *)
-
-(** The tactic [unify_abstract_cbv_interp_rhs_reflexivity] runs the interpretation
- reduction strategies in [RHS] and unifies the result with [LHS],
- and does not use the vm (and hence does not fully reduce things,
- which is important for efficiency). *)
-Ltac unify_abstract_cbv_interp_rhs_reflexivity :=
- intros; clear;
- lazymatch goal with
- | [ |- ?LHS = ?RHS ]
- => let RHS' := (eval interp_red in RHS) in
- let RHS' := (eval extra_interp_red in RHS') in
- let RHS' := lazymatch do_constant_simplification with
- | true => (eval constant_simplification in RHS')
- | _ => RHS'
- end in
- 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 :=
- post_intro_interp_flat_type_intros;
- 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 PointedProp.to_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],
- and add extra equality hypotheses to minimize the work we have to
- do in Ltac. *)
-(** *** Gallina assembly imports *)
-Require Import Crypto.Compilers.Syntax.
-Require Import Crypto.Compilers.SmartMap.
-Require Import Crypto.Compilers.Wf.
-Require Import Crypto.Compilers.WfReflectiveGen.
-Require Import Crypto.Compilers.WfReflective.
-Require Import Crypto.Compilers.Eta.
-Require Import Crypto.Compilers.EtaWf.
-Require Import Crypto.Compilers.EtaInterp.
-Require Import Crypto.Compilers.Z.Bounds.Pipeline.OutputType.
-Require Import Crypto.Compilers.Z.Bounds.Pipeline.Definition.
-Require Import Crypto.Compilers.Z.Syntax.
-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.
-
-(** *** Gallina assembly *)
-Section with_round_up_list.
- Context {allowable_lgsz : list nat}.
-
- Local Notation pick_typeb := (@Bounds.bounds_to_base_type (Bounds.round_up_to_in_list allowable_lgsz)) (only parsing).
- Local Notation pick_type v := (SmartFlatTypeMap pick_typeb v).
-
- Context (opts : PipelineOptions)
- {t : type base_type}
- {input_bounds : interp_flat_type Bounds.interp_base_type (domain t)}
- {given_output_bounds : interp_flat_type Bounds.interp_base_type (codomain t)}
- {v' : interp_flat_type interp_base_type (pick_type input_bounds)}
- {fZ : interp_flat_type interp_base_type (domain t)
- -> interp_flat_type interp_base_type (codomain t)}
- {final_e_evar : interp_flat_type interp_base_type (pick_type given_output_bounds)}.
-
- Class PipelineEvars :=
- {
- b : interp_flat_type Bounds.interp_base_type (codomain t);
- e' : Expr (pick_type input_bounds -> pick_type b);
- e_final_newtype : Expr (pick_type input_bounds -> pick_type given_output_bounds);
- e : Expr (domain t -> codomain t);
- e_pre_pkg : Expr (domain t -> codomain t);
- e_pkg : option (@ProcessedReflectivePackage allowable_lgsz)
- }.
-
- Context (evars : PipelineEvars)
-
- (** ** reification *)
- (rexpr_sig : { rexpr : Expr t | forall x, Interp rexpr x = fZ x }).
-
- Record PipelineSideConditions :=
- {
- (** ** pre-wf pipeline *)
- He : e = PreWfPipeline (proj1_sig rexpr_sig);
- (** ** proving wf *)
- He_unnatize_for_wf : forall var, unnatize_expr 0 (ExprEta' e (fun t => (nat * var t)%type)) = ExprEta' e _;
- 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 = PostWfBoundsPipeline _ opts e e_pre_pkg input_bounds;
- Hpost_correct : Some {| OutputType.input_expr := e ; OutputType.input_bounds := input_bounds ; output_bounds := b ; output_expr := e' |} = e_pkg;
- (** ** bounds relaxation *)
- Hbounds_relax : Bounds.is_tighter_thanb b given_output_bounds = true;
- Hbounds_sane : pick_type given_output_bounds = pick_type b;
- Hbounds_sane_refl
- : e_final_newtype
- = eq_rect _ (fun t => Expr (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 conditions (boundedness) *)
- Hv1 : Bounds.is_bounded_by input_bounds (cast_back_flat_const v');
- Hv2 : intros_interp_flat_type_Prop (fun v => PointedProp.to_prop (InterpSideConditions e_pre_pkg v));
- }.
-
- Definition PipelineCorrect
- (side_conditions : PipelineSideConditions)
- : 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 using All.
- destruct side_conditions
- as [He He_unnatize_for_wf Hwf Hpost_wf_pre_bounds Hpost Hpost_correct Hbounds_relax Hbounds_sane Hbounds_sane_refl Hevar Hv1 Hv2].
- cbv [b e' e_final_newtype e e_pre_pkg e_pkg] in *.
- destruct evars as [b e' e_final_newtype e e_pre_pkg e_pkg];
- clear evars.
- destruct rexpr_sig as [? Hrexpr]; clear rexpr_sig.
- assert (Hwf' : Wf e)
- by (apply (proj1 (@Wf_ExprEta'_iff _ _ _ e));
- eapply reflect_Wf;
- [ .. | intros; split; [ eapply He_unnatize_for_wf | rewrite <- Hwf; apply trueify_true ] ];
- auto using base_type_eq_semidec_is_dec, op_beq_bl).
- clear Hwf He_unnatize_for_wf.
- symmetry in Hpost_correct.
- subst; cbv [proj1_sig] in *.
- rewrite eq_InterpEta, <- Hrexpr.
- pose proof (introsP_interp_flat_type Hv2) as Hv2'.
- eapply PostWfPipelineCorrect in Hpost_correct; [ | solve [ eauto ].. ].
- rewrite !@InterpPreWfPipeline in Hpost_correct.
- unshelve eapply relax_output_bounds; try eassumption; [].
- match goal with
- | [ |- context[Interp (@eq_rect ?A ?x ?P ?k ?y ?pf) ?v] ]
- => rewrite (@ap_transport A P _ x y pf (fun t e => Interp e v) k)
- end.
- rewrite <- transport_pp, concat_Vp; simpl.
- apply Hpost_correct.
- Qed.
-End with_round_up_list.
-
-(** ** Assembling the Pipeline, in Ltac *)
-(** The tactic [refine_with_pipeline_correct] uses the
- [PipelineCorrect] lemma to create side-conditions. It assumes the
- goal is in exactly the form given in the conclusion of the
- [PipelineCorrect] lemma. *)
-(** The [refine_PipelineSideConditions_constructor] subtactic splits
- up the [PipelineSideConditions] record goal into multiple
- subgoals, to be discharged by automation lower in this file
- ([solve_post_reified_side_conditions]). *)
-Ltac refine_PipelineSideConditions_constructor :=
- lazymatch goal with
- | [ |- PipelineSideConditions ?opts ?evars _ ]
- => simple refine {| Hevar := _ |};
- cbv [b e' e_final_newtype e e_pre_pkg e_pkg proj1_sig]
- end.
-Ltac refine_with_pipeline_correct opts :=
- lazymatch goal with
- | [ |- _ /\ ?castback ?fW = ?fZ ?arg ]
- => let lem := open_constr:(@PipelineCorrect _ opts _ _ _ _ _ _ {| e_pkg := _ |}) in
- simple refine (lem _ _);
- subst fW fZ
- end;
- [ eexists
- | refine_PipelineSideConditions_constructor ].
-
-(** The tactic [solve_side_conditions] uses the above
- reduction-and-proving-equality tactics to prove the
- side-conditions of [PipelineCorrect]. The order must match with
- [PipelineCorrect]. Which tactic to use was chosen in the
- following way:
-
- - The default is [unify_abstract_vm_compute_rhs_reflexivity]
-
- - If the [RHS] is already in [vm_compute]d form, use
- [unify_abstract_rhs_reflexivity] (saves a needless [vm_compute] which would be a
- costly no-op)
-
- - If the proof needs to be transparent and there are no evars and
- you want the user to see the fully [vm_compute]d term on error,
- use [vm_compute; reflexivity]
-
- - If the user should see an unreduced term and you're proving [_ =
- true], use [abstract vm_cast_no_check (eq_refl true)]
-
- - If you want to preserve binder names, use [unify_abstract_cbv_rhs_reflexivity]
-
- The other choices are tactics that are specialized to the specific
- side-condition for which they are used (reification, boundedness
- of input, reduction of [Interp], renaming). *)
-Ltac solve_post_reified_side_conditions :=
- [>
- (** ** pre-wf pipeline *)
- unify_abstract_vm_compute_rhs_reflexivity |
- (** ** reflective wf side-condition 1 *)
- 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 _] *)
- unify_abstract_rhs_reflexivity |
- (** ** computed output bounds are not looser than the given output bounds *)
- (** we do subst and we don't [vm_compute] first because we want to
- get an error message that displays the bounds *)
- subst_let; clear; abstract vm_cast_no_check (eq_refl true) |
- (** ** types computed from given output bounds are the same as types computed from computed output bounds *)
- (** N.B. the proof must be exactly [eq_refl] because it's used in a
- later goal and needs to reduce *)
- subst_let; clear; vm_compute; reflexivity |
- (** ** removal of a cast across the equality proof above *)
- unify_abstract_compute_rhs_reflexivity |
- (** ** unfolding of [interp] constants *)
- unify_abstract_cbv_interp_rhs_reflexivity |
- (** ** boundedness of inputs *)
- abstract handle_bounds_from_hyps |
- (** ** boundedness side-condition *)
- handle_boundedness_side_condition ].
-Ltac solve_side_conditions :=
- [>
- (** ** reification *)
- do_reify |
- .. ];
- solve_post_reified_side_conditions.
-
-(** ** The Entire Pipeline *)
-(** The [do_reflective_pipeline] tactic solves a goal of the form that
- is described at the top of this file, and is the public interface
- of this file. *)
-Ltac do_reflective_pipeline opts :=
- refine_with_pipeline_correct opts; solve_side_conditions.
-Notation default_PipelineOptions := default_PipelineOptions.