blob: 999fbe1ed4c842154c0ef1f60fa9e8c572e8b4cf (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
|
Require Import Crypto.Util.Sigma.Lift.
Require Import Crypto.Util.Sigma.Associativity.
Require Import Crypto.Util.Sigma.MapProjections.
Require Import Crypto.Specific.IntegrationTestTemporaryMiscCommon.
Require Import Crypto.Compilers.Z.Bounds.Interpretation.
Require Import Crypto.Compilers.Eta.
Require Import Coq.ZArith.ZArith.
Require Import Crypto.Util.LetIn.
Require Import Crypto.Util.FixedWordSizes.
Require Import Crypto.Compilers.Syntax.
Require Export Crypto.Util.Notations.
Global Arguments Pos.to_nat !_ / .
Ltac display_helper_gen f make_hole :=
let display_helper f := display_helper_gen f make_hole in
let do_make_hole _ :=
match goal with
| [ |- ?T ] => let h := make_hole T in
refine h
end in
let t := type of f in
lazymatch (eval hnf in t) with
| forall _ : ?A, ?B
=> let x := fresh "x" in
lazymatch (eval hnf in A) with
| @sig ?A ?P
=> lazymatch (eval hnf in A) with
| sig _
=> let f' := constr:(fun x : A => f (exist P x ltac:(do_make_hole ()))) in
display_helper f'
| _
=> refine (fun x : A => _);
let f' := constr:(f (exist P x ltac:(do_make_hole ()))) in
display_helper f'
end
| _
=> lazymatch A with
| prod ?A ?B
=> let f' := constr:(fun (a : A) (b : B) => f (a, b)%core) in
display_helper f'
| _
=> refine (fun x : A => _);
let f' := constr:(f x) in
display_helper f'
end
end
| @sig ?A _
=> lazymatch (eval hnf in A) with
| sig _ => display_helper (proj1_sig f)
| _ => refine (proj1_sig f)
end
| _
=> lazymatch t with
| prod _ _
=> let a := fresh "a" in
let b := fresh "b" in
refine (let (a, b) := f in
pair _ _);
[ display_helper a | display_helper b ]
| _ => refine f
end
end.
Ltac display_helper f := display_helper_gen f ltac:(fun T => open_constr:(_)).
Ltac display_helper_with_admit f :=
constr:(fun admit : forall T, T
=> ltac:(display_helper_gen f ltac:(fun T => constr:(admit T)))).
Ltac try_strip_admit f :=
lazymatch f with
| fun _ : forall T, T => ?P => P
| ?P => P
end.
Ltac refine_display f :=
let do_red F := (eval cbv [f
proj1_sig fst snd
Tuple.map Tuple.map'
Lift.lift1_sig Lift.lift2_sig Lift.lift3_sig Lift.lift4_sig Lift.lift4_sig_sig
MapProjections.proj2_sig_map Associativity.sig_sig_assoc
sig_conj_by_impl2
sig_eq_trans_exist1 sig_R_trans_exist1 sig_eq_trans_rewrite_fun_exist1
sig_R_trans_rewrite_fun_exist1
adjust_tuple2_tuple2_sig
Tuple.tuple Tuple.tuple'
FixedWordSizes.wordT FixedWordSizes.word_case FixedWordSizes.ZToWord FixedWordSizes.word_case_dep
Bounds.actual_logsz Bounds.round_up_to_in_list Bounds.option_min
List.map List.filter List.fold_right List.fold_left
Nat.leb Nat.min
PeanoNat.Nat.log2 PeanoNat.Nat.log2_iter PeanoNat.Nat.pred
Bounds.bounds_to_base_type
interp_flat_type
Z.leb Z.compare Pos.compare Pos.compare_cont
ZRange.lower ZRange.upper
BinPos.Pos.to_nat PeanoNat.Nat.pow
] in F) in
let ret := display_helper_with_admit (proj1_sig f) in
let ret := do_red ret in
let ret := lazymatch ret with
| context[match ?sz with O => _ | _ => _ end] => (eval cbv [sz] in ret)
| _ => ret
end in
let ret := (eval simpl @Z.to_nat in ret) in
let ret := (eval cbv [interp_flat_type] in ret) in
let ret := try_strip_admit ret in
refine ret.
Tactic Notation "display" open_constr(f) :=
refine_display f.
Notation display f := (ltac:(let v := f in display v)) (only parsing).
(** Some helper tactics for actually pulling out the expression *)
Ltac strip_InterpEta term :=
let retype e :=
lazymatch type of e with
| forall var, @Syntax.expr ?base_type_code ?op var ?T
=> constr:(e : @Syntax.Expr base_type_code op T)
| _ => e
end in
lazymatch term with
| fun x : ?T => ?P
=> let maybe_x := fresh x in
let probably_not_x := fresh maybe_x in
let not_x := fresh probably_not_x in
lazymatch
constr:(fun x : T
=> match P with
| not_x => ltac:(let v := (eval cbv delta [not_x] in not_x) in
let v' := strip_InterpEta v in
exact v')
end)
with
| fun _ => ?P => retype P
| ?P => retype P
end
| @Eta.InterpEta _ _ _ _ _ ?e
=> e
| @Eta.InterpEta _ _ _ _ _ ?e _
=> e
| let (a, b) := ?f in _
=> f
| _ => let dummy := match goal with
| _ => fail 1 "strip_InterpEta:" term
end in
I
end.
Ltac extract_Expr f :=
let k := constr:(ltac:(refine_display f)) in
let k := strip_InterpEta k in
k.
Notation extract_Expr f := (ltac:(let v := f in let v := extract_Expr v in refine v)) (only parsing).
|