Skip to content

Commit f9c62c5

Browse files
authored
Merge pull request #1059 from MetaCoq/reorder-constructors
Reorder constructors
2 parents 9e3e264 + e622b43 commit f9c62c5

File tree

7 files changed

+172
-32
lines changed

7 files changed

+172
-32
lines changed

erasure-plugin/_PluginProject.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ src/eConstructorsAsBlocks.mli
120120
src/eConstructorsAsBlocks.ml
121121
src/eCoInductiveToInductive.mli
122122
src/eCoInductiveToInductive.ml
123+
src/eReorderCstrs.mli
124+
src/eReorderCstrs.ml
123125
src/eTransform.mli
124126
src/eTransform.ml
125127
src/erasure0.mli

erasure-plugin/src/g_metacoq_erasure.mlg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ let make_erasure_config config =
6363
enable_typed_erasure = config.typed;
6464
enable_fast_remove_params = config.fast;
6565
dearging_config = default_dearging_config;
66-
}
66+
inductives_mapping = [] }
6767

6868
let time_opt config str fn arg =
6969
if config.time then

erasure-plugin/src/metacoq_erasure_plugin.mlpack

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ EOptimizePropDiscr
6565
EInlineProjections
6666
EConstructorsAsBlocks
6767
ECoInductiveToInductive
68+
EReorderCstrs
6869
EProgram
6970
OptimizePropDiscr
7071

erasure-plugin/theories/ETransform.v

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ Set Warnings "-notation-overridden".
88
From MetaCoq.PCUIC Require PCUICAst PCUICAstUtils PCUICProgram PCUICWeakeningEnvSN.
99
Set Warnings "+notation-overridden".
1010
From MetaCoq.SafeChecker Require Import PCUICErrors PCUICWfEnv PCUICWfEnvImpl.
11-
From MetaCoq.Erasure Require EAstUtils ErasureCorrectness Extract EOptimizePropDiscr ERemoveParams EProgram.
11+
From MetaCoq.Erasure Require EAstUtils ErasureCorrectness Extract EOptimizePropDiscr
12+
ERemoveParams EProgram.
1213
From MetaCoq.Erasure Require Import ErasureFunction ErasureFunctionProperties.
1314
From MetaCoq.TemplatePCUIC Require Import PCUICTransform.
1415

@@ -1023,6 +1024,45 @@ Proof.
10231024
eapply ECoInductiveToInductive.trust_cofix.
10241025
Qed.
10251026

1027+
From MetaCoq.Erasure Require Import EReorderCstrs.
1028+
1029+
Axiom trust_reorder_cstrs_wf :
1030+
forall efl : EEnvFlags,
1031+
WcbvFlags ->
1032+
forall (m : inductives_mapping) (input : Transform.program E.global_context term),
1033+
wf_eprogram efl input -> wf_eprogram efl (reorder_program m input).
1034+
Axiom trust_reorder_cstrs_pres :
1035+
forall (efl : EEnvFlags) (wfl : WcbvFlags) (m : inductives_mapping) (p : Transform.program E.global_context term)
1036+
(v : term),
1037+
wf_eprogram efl p ->
1038+
eval_eprogram wfl p v -> exists v' : term, eval_eprogram wfl (reorder_program m p) v' /\ v' = reorder m v.
1039+
1040+
Program Definition reorder_cstrs_transformation (efl : EEnvFlags) (wfl : WcbvFlags) (m : inductives_mapping) :
1041+
Transform.t _ _ EAst.term EAst.term _ _
1042+
(eval_eprogram wfl) (eval_eprogram wfl) :=
1043+
{| name := "reoder inductive constructors ";
1044+
transform p _ := EReorderCstrs.reorder_program m p ;
1045+
pre p := wf_eprogram efl p ;
1046+
post p := wf_eprogram efl p ;
1047+
obseq p hp p' v v' := v' = EReorderCstrs.reorder m v |}.
1048+
1049+
Next Obligation.
1050+
move=> efl wfl m. cbn. now apply trust_reorder_cstrs_wf.
1051+
Qed.
1052+
Next Obligation.
1053+
red. eapply trust_reorder_cstrs_pres.
1054+
Qed.
1055+
1056+
#[global]
1057+
Axiom trust_reorder_cstrs_transformation_ext : forall (efl : EEnvFlags) (wfl : WcbvFlags) (m : inductives_mapping),
1058+
TransformExt.t (reorder_cstrs_transformation efl wfl m)
1059+
(fun p p' => extends p.1 p'.1) (fun p p' => extends p.1 p'.1).
1060+
1061+
#[global]
1062+
Axiom trust_reorder_cstrs_transformation_ext' : forall (efl : EEnvFlags) (wfl : WcbvFlags) (m : inductives_mapping),
1063+
TransformExt.t (reorder_cstrs_transformation efl wfl m)
1064+
extends_eprogram extends_eprogram.
1065+
10261066
Program Definition optional_transform {env env' term term' value value' eval eval'} (activate : bool)
10271067
(tr : Transform.t env env' term term' value value' eval eval') :
10281068
if activate then Transform.t env env' term term' value value' eval eval'

erasure-plugin/theories/Erasure.v

Lines changed: 29 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ Record erasure_configuration := {
3434
enable_cofix_to_fix : bool;
3535
enable_typed_erasure : bool;
3636
enable_fast_remove_params : bool;
37-
dearging_config : dearging_config
37+
dearging_config : dearging_config;
38+
inductives_mapping : EReorderCstrs.inductives_mapping
3839
}.
3940

4041
Definition default_dearging_config :=
@@ -47,14 +48,16 @@ Definition default_erasure_config :=
4748
{| enable_cofix_to_fix := true;
4849
dearging_config := default_dearging_config;
4950
enable_typed_erasure := true;
50-
enable_fast_remove_params := true |}.
51+
enable_fast_remove_params := true;
52+
inductives_mapping := [] |}.
5153

5254
(* This runs only the verified phases without the typed erasure and "fast" remove params *)
5355
Definition safe_erasure_config :=
5456
{| enable_cofix_to_fix := false;
5557
enable_typed_erasure := false;
5658
enable_fast_remove_params := false;
57-
dearging_config := default_dearging_config |}.
59+
dearging_config := default_dearging_config;
60+
inductives_mapping := [] |}.
5861

5962
Axiom assume_welltyped_template_program_expansion :
6063
forall p (wtp : ∥ wt_template_program_env p ∥),
@@ -89,7 +92,7 @@ Definition final_wcbv_flags := {|
8992
with_guarded_fix := false;
9093
with_constructor_as_block := true |}.
9194

92-
Program Definition optional_cofix_to_fix_transform econf :=
95+
Program Definition optional_unsafe_transforms econf :=
9396
ETransform.optional_self_transform econf.(enable_cofix_to_fix)
9497
((* Rebuild the efficient lookup table *)
9598
rebuild_wf_env_transform (efl := EConstructorsAsBlocks.switch_cstr_as_blocks
@@ -98,8 +101,8 @@ Program Definition optional_cofix_to_fix_transform econf :=
98101
let efl := EConstructorsAsBlocks.switch_cstr_as_blocks
99102
(EInlineProjections.disable_projections_env_flag (ERemoveParams.switch_no_params EWellformed.all_env_flags)) in
100103
coinductive_to_inductive_transformation efl
101-
(has_app := eq_refl) (has_box := eq_refl) (has_rel := eq_refl) (has_pars := eq_refl) (has_cstrblocks := eq_refl))
102-
.
104+
(has_app := eq_refl) (has_box := eq_refl) (has_rel := eq_refl) (has_pars := eq_refl) (has_cstrblocks := eq_refl)
105+
reorder_cstrs_transformation efl final_wcbv_flags econf.(inductives_mapping)).
103106

104107
Program Definition verified_lambdabox_pipeline {guard : abstract_guard_impl}
105108
(efl := EWellformed.all_env_flags)
@@ -237,32 +240,26 @@ Program Definition verified_lambdabox_typed_pipeline {guard : abstract_guard_imp
237240
constructors_as_blocks_transformation
238241
(efl := EInlineProjections.disable_projections_env_flag (ERemoveParams.switch_no_params EWellformed.all_env_flags))
239242
(has_app := eq_refl) (has_pars := eq_refl) (has_rel := eq_refl) (has_box := eq_refl) (has_cstrblocks := eq_refl) ▷
240-
ETransform.optional_self_transform econf.(enable_cofix_to_fix)
241-
((* Rebuild the efficient lookup table *)
242-
rebuild_wf_env_transform (efl := EConstructorsAsBlocks.switch_cstr_as_blocks
243-
(EInlineProjections.disable_projections_env_flag (ERemoveParams.switch_no_params EWellformed.all_env_flags))) false false ▷
244-
(* Coinductives & cofixpoints are translated to inductive types and thunked fixpoints *)
245-
let efl := EConstructorsAsBlocks.switch_cstr_as_blocks
246-
(EInlineProjections.disable_projections_env_flag (ERemoveParams.switch_no_params EWellformed.all_env_flags)) in
247-
coinductive_to_inductive_transformation efl
248-
(has_app := eq_refl) (has_box := eq_refl) (has_rel := eq_refl) (has_pars := eq_refl) (has_cstrblocks := eq_refl))
249-
.
243+
optional_unsafe_transforms econf.
250244

251245
(* At the end of erasure we get a well-formed program (well-scoped globally and localy), without
252246
parameters in inductive declarations. The constructor applications are also transformed to a first-order
253247
"block" application, of the right length, and the evaluation relation does not need to consider guarded
254248
fixpoints or case analyses on propositional content. All fixpoint bodies start with a lambda as well.
255249
Finally, projections are inlined to cases, so no `tProj` remains. *)
256250

257-
Import EGlobalEnv EWellformed.
251+
Import EGlobalEnv EWellformed.
252+
253+
Next Obligation.
254+
destruct H. split => //. sq.
255+
now eapply ETransform.expanded_eprogram_env_expanded_eprogram_cstrs.
256+
Qed.
258257

259-
Next Obligation.
260-
destruct H. split => //. sq.
261-
now eapply ETransform.expanded_eprogram_env_expanded_eprogram_cstrs.
262-
Qed.
263-
Next Obligation.
264-
destruct H. destruct enable_cofix_to_fix => //.
265-
Qed.
258+
Next Obligation.
259+
unfold optional_unsafe_transforms. cbn.
260+
unfold optional_self_transform. cbn.
261+
destruct enable_cofix_to_fix => //.
262+
Qed.
266263

267264
Local Obligation Tactic := intros; eauto.
268265

@@ -340,7 +337,7 @@ Program Definition erasure_pipeline_fast {guard : abstract_guard_impl} (efl := E
340337
let efl := EInlineProjections.disable_projections_env_flag (ERemoveParams.switch_no_params EWellformed.all_env_flags) in
341338
rebuild_wf_env_transform (efl := efl) true false ▷
342339
constructors_as_blocks_transformation (efl := efl) (has_app := eq_refl) (has_pars := eq_refl) (has_rel := eq_refl) (has_box := eq_refl) (has_cstrblocks := eq_refl) ▷
343-
optional_cofix_to_fix_transform econf.
340+
optional_unsafe_transforms econf.
344341
Next Obligation.
345342
destruct H; split => //. now eapply ETransform.expanded_eprogram_env_expanded_eprogram_cstrs.
346343
Qed.
@@ -360,7 +357,7 @@ Next Obligation.
360357
cbn in H. split; cbn; intuition eauto.
361358
Qed.
362359
Next Obligation.
363-
cbn in H. unfold optional_cofix_to_fix_transform. destruct enable_cofix_to_fix => //.
360+
cbn in H. unfold optional_unsafe_transforms. destruct enable_cofix_to_fix => //.
364361
Qed.
365362
Next Obligation.
366363
cbn in H. split; cbn; intuition eauto.
@@ -401,10 +398,10 @@ Program Definition run_erase_program {guard : abstract_guard_impl} econf :=
401398
if econf.(enable_typed_erasure) then run (typed_erasure_pipeline econf)
402399
else if econf.(enable_fast_remove_params) then
403400
run (erasure_pipeline_fast econf)
404-
else run (erasure_pipeline ▷ (optional_cofix_to_fix_transform econf)).
401+
else run (erasure_pipeline ▷ (optional_unsafe_transforms econf)).
405402
Next Obligation.
406403
Proof.
407-
unfold optional_cofix_to_fix_transform.
404+
unfold optional_unsafe_transforms.
408405
destruct enable_cofix_to_fix => //.
409406
Qed.
410407

@@ -423,7 +420,8 @@ Definition erasure_fast_config :=
423420
{| enable_cofix_to_fix := false;
424421
dearging_config := default_dearging_config;
425422
enable_typed_erasure := false;
426-
enable_fast_remove_params := true |}.
423+
enable_fast_remove_params := true;
424+
inductives_mapping := [] |}.
427425

428426
Program Definition erase_fast_and_print_template_program (p : Ast.Env.program) : string :=
429427
erase_and_print_template_program erasure_fast_config p.
@@ -432,7 +430,8 @@ Definition typed_erasure_config :=
432430
{| enable_cofix_to_fix := false;
433431
dearging_config := default_dearging_config;
434432
enable_typed_erasure := true;
435-
enable_fast_remove_params := true |}.
433+
enable_fast_remove_params := true;
434+
inductives_mapping := [] |}.
436435

437436
(* Parameterized by a configuration for dearging, allowing to, e.g., override masks. *)
438437
Program Definition typed_erase_and_print_template_program (p : Ast.Env.program)

erasure/_CoqProject.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ theories/EConstructorsAsBlocks.v
3939
theories/EWcbvEvalCstrsAsBlocksInd.v
4040
theories/EWcbvEvalCstrsAsBlocksFixLambdaInd.v
4141
theories/ECoInductiveToInductive.v
42+
theories/EReorderCstrs.v
4243
theories/EImplementBox.v
4344

4445
theories/Typed/Annotations.v

erasure/theories/EReorderCstrs.v

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
From Coq Require Import List String Arith Lia.
2+
Import ListNotations.
3+
From Equations Require Import Equations.
4+
Set Equations Transparent.
5+
6+
From MetaCoq.PCUIC Require Import PCUICAstUtils.
7+
From MetaCoq.Utils Require Import MCList bytestring utils monad_utils.
8+
From MetaCoq.Erasure Require Import EPrimitive EAst ESpineView EEtaExpanded EInduction ERemoveParams Erasure EGlobalEnv.
9+
10+
Import Kernames.
11+
Import MCMonadNotation.
12+
13+
Definition inductive_mapping : Set := Kernames.inductive * (bytestring.string * list nat).
14+
Definition inductives_mapping := list inductive_mapping.
15+
16+
Fixpoint lookup_inductive {A} (Σ : list (inductive × A)) (kn : inductive) {struct Σ} : option A :=
17+
match Σ with
18+
| [] => None
19+
| d :: tl => if kn == d.1 then Some d.2 else lookup_inductive tl kn
20+
end.
21+
22+
Section Reorder.
23+
Context (Σ : global_declarations).
24+
Context (mapping : inductives_mapping).
25+
26+
Definition lookup_constructor_mapping i m :=
27+
'(tyna, tags) <- lookup_inductive mapping i ;;
28+
List.nth_error tags m.
29+
30+
Definition lookup_constructor_ordinal i m :=
31+
match lookup_constructor_mapping i m with
32+
| None => m
33+
| Some m' => m'
34+
end.
35+
36+
Definition reorder_list_opt {A} tags (brs : list A) : option (list A) :=
37+
mapopt (nth_error brs) tags.
38+
39+
Definition reorder_list {A} tags (l : list A) :=
40+
option_get l (reorder_list_opt tags l).
41+
42+
Definition reorder_branches (i : inductive) (brs : list (list BasicAst.name × term)) : list (list BasicAst.name × term) :=
43+
match lookup_inductive mapping i with
44+
| None => brs
45+
| Some (tyna, tags) => reorder_list tags brs
46+
end.
47+
48+
Equations reorder (t : term) : term :=
49+
| tVar na => tVar na
50+
| tLambda nm bod => tLambda nm (reorder bod)
51+
| tLetIn nm dfn bod => tLetIn nm dfn bod
52+
| tApp fn arg => tApp (reorder fn) (reorder arg)
53+
| tConst nm => tConst nm
54+
| tConstruct i m args => tConstruct i (lookup_constructor_ordinal i m) (map reorder args)
55+
| tCase i mch brs => tCase i mch (reorder_branches i.1 (map (on_snd reorder) brs))
56+
| tFix mfix idx => tFix (map (map_def reorder) mfix) idx
57+
| tCoFix mfix idx => tCoFix (map (map_def reorder) mfix) idx
58+
| tProj (Kernames.mkProjection ind i arg) bod =>
59+
tProj (Kernames.mkProjection ind i (lookup_constructor_ordinal ind arg)) (reorder bod)
60+
| tPrim p => tPrim (map_prim reorder p)
61+
| tLazy t => tLazy (reorder t)
62+
| tForce t => tForce (reorder t)
63+
| tRel n => tRel n
64+
| tBox => tBox
65+
| tEvar ev args => tEvar ev (map reorder args).
66+
67+
Definition reorder_constant_decl cb :=
68+
{| cst_body := option_map reorder cb.(cst_body) |}.
69+
70+
Definition reorder_one_ind kn i (oib : one_inductive_body) : one_inductive_body :=
71+
match lookup_inductive mapping {| inductive_mind := kn; inductive_ind := i |} with
72+
| None => oib
73+
| Some (tyna, tags) =>
74+
{| ind_name := oib.(ind_name);
75+
ind_propositional := oib.(ind_propositional);
76+
ind_kelim := oib.(ind_kelim);
77+
ind_ctors := reorder_list tags oib.(ind_ctors);
78+
ind_projs := reorder_list tags oib.(ind_projs) |}
79+
end.
80+
81+
Definition reorder_inductive_decl kn idecl :=
82+
{| ind_finite := idecl.(ind_finite); ind_npars := 0;
83+
ind_bodies := mapi (reorder_one_ind kn) idecl.(ind_bodies) |}.
84+
85+
Definition reorder_decl d :=
86+
match d.2 with
87+
| ConstantDecl cb => (d.1, ConstantDecl (reorder_constant_decl cb))
88+
| InductiveDecl idecl => (d.1, InductiveDecl (reorder_inductive_decl d.1 idecl))
89+
end.
90+
91+
Definition reorder_env Σ :=
92+
map (reorder_decl) Σ.
93+
94+
End Reorder.
95+
96+
Definition reorder_program mapping (p : program) : program :=
97+
(reorder_env mapping p.1, reorder mapping p.2).

0 commit comments

Comments
 (0)