Skip to content

Commit 9df4315

Browse files
committed
derive: param1 support for is_true and primitive strings
1 parent 19cc599 commit 9df4315

File tree

4 files changed

+152
-73
lines changed

4 files changed

+152
-73
lines changed

apps/derive/tests/test_param1_trivial.v

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,3 +104,8 @@ Redirect "tmp" Check is_sigma_bool_inhab : full sigma_bool is_sigma_bool.
104104
Redirect "tmp" Check is_ord_inhab : forall p px, full (ord p) (is_ord p px).
105105
Redirect "tmp" Check is_ord2_inhab : forall p px, full (ord2 p) (is_ord2 p px).
106106
Redirect "tmp" Check is_val_inhab : full val is_val.
107+
108+
Redirect "tmp" Record sigma_bool2 := { depn : peano; depeq : lib:elpi.is_true (is_zero depn) }.
109+
Redirect "tmp" Elpi derive.param1 sigma_bool2.
110+
Redirect "tmp" Elpi derive.param1.trivial is_sigma_bool2.
111+
Redirect "tmp" Check is_sigma_bool2_inhab.

apps/derive/theories/derive/param1.v

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,9 @@ Register is_uint63 as elpi.derive.is_uint63.
4949
Inductive is_float64 : PrimFloat.float -> Type := float64 (f : PrimFloat.float ) : is_float64 f.
5050
Register is_float64 as elpi.derive.is_float64.
5151

52+
Inductive is_pstring : lib:elpi.pstring -> Type := pstring (s : lib:elpi.pstring) : is_pstring s.
53+
Register is_pstring as elpi.derive.is_pstring.
54+
5255
(* Links a term (constant, inductive type, inductive constructor) with
5356
its parametricity translation *)
5457
Elpi Db derive.param1.db lp:{{
@@ -62,6 +65,7 @@ pred reali-done i:gref.
6265

6366
reali {{ lib:num.int63.type }} {{ lib:elpi.derive.is_uint63 }} :- !.
6467
reali {{ lib:num.float.type }} {{ lib:elpi.derive.is_float64 }} :- !.
68+
reali {{ lib:elpi.pstring }} {{ lib:elpi.derive.is_pstring }} :- !.
6569

6670
:name "reali:fail"
6771
reali X _ :-
@@ -71,6 +75,7 @@ reali X _ :-
7175

7276
realiR {{ lib:num.int63.type }} {{ lib:elpi.derive.is_uint63 }} :- !.
7377
realiR {{ lib:num.float.type }} {{ lib:elpi.derive.is_float64 }} :- !.
78+
realiR {{ lib:elpi.pstring }} {{ lib:elpi.derive.is_pstring }} :- !.
7479

7580
:name "realiR:fail"
7681
realiR T TR :-
@@ -93,10 +98,20 @@ Elpi Accumulate lp:{{
9398
}}.
9499

95100
Module Export exports.
101+
102+
Local Notation core_is_true := is_true. (* avoid shadowing by param1 is_true *)
103+
96104
Elpi derive.param1 eq.
105+
Elpi derive.param1 bool.
106+
Elpi derive.param1 core_is_true.
107+
97108
End exports.
98-
Register is_eq as elpi.derive.is_eq.
99109

110+
Register is_eq as elpi.derive.is_eq.
111+
Register is_bool as elpi.derive.is_bool.
112+
Register is_true as elpi.derive.is_true.
113+
Register is_false as elpi.derive.is_false.
114+
Register is_is_true as elpi.derive.is_is_true.
100115

101116
(* hook into derive *)
102117
Elpi Accumulate derive File paramX.

apps/derive/theories/derive/param1_trivial.v

Lines changed: 129 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -16,58 +16,7 @@ From elpi.apps.derive.elpi Extra Dependency "derive_synterp_hook.elpi" as derive
1616
From elpi Require Import elpi.
1717
From elpi.apps Require Import derive.param1 derive.param1_congr.
1818

19-
20-
Definition is_uint63_inhab x : is_uint63 x. Proof. constructor. Defined.
21-
Register is_uint63_inhab as elpi.derive.is_uint63_inhab.
22-
23-
Definition is_float64_inhab x : is_float64 x. Proof. constructor. Defined.
24-
Register is_float64_inhab as elpi.derive.is_float64_inhab.
25-
26-
Definition is_eq_inhab
27-
A (PA : A -> Type) (HA : trivial A PA) (x : A) (px: PA x) y (py : PA y) (eq_xy : x = y) :
28-
is_eq A PA x px y py eq_xy.
29-
Proof.
30-
revert py.
31-
case eq_xy; clear eq_xy y.
32-
intro py.
33-
rewrite <- (trivial_uniq A PA HA x px); clear px.
34-
rewrite <- (trivial_uniq A PA HA x py); clear py.
35-
apply (is_eq_refl A PA x (trivial_full A PA HA x)).
36-
Defined.
37-
Register is_eq_inhab as elpi.derive.is_eq_inhab.
38-
39-
Definition is_uint63_trivial : trivial PrimInt63.int is_uint63 :=
40-
fun x => contracts _ is_uint63 x (is_uint63_inhab x)
41-
(fun y => match y with uint63 i => eq_refl end).
42-
Register is_uint63_trivial as elpi.derive.is_uint63_trivial.
43-
44-
Definition is_float64_trivial : trivial PrimFloat.float is_float64 :=
45-
fun x => contracts _ is_float64 x (is_float64_inhab x)
46-
(fun y => match y with float64 i => eq_refl end).
47-
Register is_float64_trivial as elpi.derive.is_float64_trivial.
48-
49-
Lemma is_eq_trivial A (PA : A -> Type) (HA : trivial A PA) (x : A) (px: PA x)
50-
y (py : PA y)
51-
: trivial (x = y) (is_eq A PA x px y py).
52-
Proof.
53-
intro p.
54-
apply (contracts (x = y) (is_eq A PA x px y py) p (is_eq_inhab A PA HA x px y py p)).
55-
revert py.
56-
case p; clear p y.
57-
rewrite <- (trivial_uniq _ _ HA x px). clear px.
58-
intros py.
59-
rewrite <- (trivial_uniq _ _ HA x py). clear py.
60-
intro v; case v; clear v.
61-
unfold is_eq_inhab.
62-
unfold trivial_full.
63-
unfold trivial_uniq.
64-
case (HA x); intros it def_it; compute.
65-
case (def_it it).
66-
reflexivity.
67-
Defined.
68-
Register is_eq_trivial as elpi.derive.is_eq_trivial.
69-
70-
Elpi Db derive.param1.trivial.db lp:{{
19+
Elpi Db derive.param1.trivial.db lp:{{
7120

7221
pred param1-trivial-done i:inductive.
7322
type param1-trivial-db term -> term -> prop.
@@ -82,13 +31,7 @@ Elpi Db derive.param1.trivial.db lp:{{
8231
#[superglobal] Elpi Accumulate derive.param1.trivial.db Db Header derive.param1.db.
8332
#[superglobal] Elpi Accumulate derive.param1.trivial.db lp:{{
8433

85-
pred coq.mk-app i:term, i:list term, o:term.
86-
pred coq.sort? i:term.
87-
88-
param1-inhab-db {{ lib:elpi.derive.is_uint63 }} {{ lib:elpi.derive.is_uint63_inhab }}.
89-
param1-inhab-db {{ lib:elpi.derive.is_float64 }} {{ lib:elpi.derive.is_float64_inhab }}.
90-
param1-inhab-db {{ lib:elpi.derive.is_eq }} {{ lib:elpi.derive.is_eq_inhab }}.
91-
34+
:name "param1:inhab:start"
9235
param1-inhab-db (fun `f` (prod `_` S _\ T) f\
9336
prod `x` S x\ prod `px` (RS x) _)
9437
(fun `f` (prod `_` S _\ T) f\
@@ -98,11 +41,6 @@ Elpi Db derive.param1.trivial.db lp:{{
9841
reali T R,
9942
param1-inhab-db R PT,
10043
coq.mk-app PT [{coq.mk-app f [x]}] (P f x).
101-
102-
param1-inhab-db
103-
{{ lib:elpi.derive.is_eq lp:A lp:PA lp:X lp:PX lp:Y lp:PY }}
104-
{{ lib:elpi.derive.is_eq_inhab lp:A lp:PA lp:QA lp:X lp:PX lp:Y lp:PY }} :- !,
105-
param1-trivial-db PA QA.
10644

10745
param1-inhab-db (app [Hd|Args]) (app[P|PArgs]) :-
10846
param1-inhab-db Hd P, !,
@@ -115,9 +53,7 @@ Elpi Db derive.param1.trivial.db lp:{{
11553
(param1-inhab-db P Q, R = [T,P,Q|PArgs], param1-inhab-db-args Args PArgs)
11654
(R = [T,P|PArgs], param1-inhab-db-args Args PArgs).
11755

118-
param1-trivial-db {{ lib:elpi.derive.is_uint63 }} {{ lib:elpi.derive.is_uint63_trivial }}.
119-
param1-trivial-db {{ lib:elpi.derive.is_float64 }} {{ lib:elpi.derive.is_float64_trivial }}.
120-
56+
:name "param1:trivial:start"
12157
param1-trivial-db (fun `f` (prod `_` S _\ T) f\
12258
prod `x` S x\ prod `px` (RS x) _)
12359
(fun `f` (prod `_` S _\ T) f\
@@ -128,11 +64,6 @@ Elpi Db derive.param1.trivial.db lp:{{
12864
param1-trivial-db R PT,
12965
coq.mk-app PT [{coq.mk-app f [x]}] (P f x).
13066

131-
param1-trivial-db
132-
{{ lib:elpi.derive.is_eq lp:A lp:PA lp:X lp:PX lp:Y lp:PY }}
133-
{{ lib:elpi.derive.is_eq_trivial lp:A lp:PA lp:QA lp:X lp:PX lp:Y lp:PY }} :-
134-
param1-trivial-db PA QA.
135-
13667
param1-trivial-db (app [Hd|Args]) (app[P|PArgs]) :-
13768
param1-trivial-db Hd P, !,
13869
param1-trivial-db-args Args PArgs.
@@ -146,6 +77,7 @@ Elpi Db derive.param1.trivial.db lp:{{
14677

14778
}}.
14879

80+
14981
(* standalone *)
15082
Elpi Command derive.param1.trivial.
15183
Elpi Accumulate File derive_hook.
@@ -184,7 +116,132 @@ Elpi Accumulate lp:{{
184116
coq.error "Usage: derive.param1.inhab <inductive type name>".
185117
}}.
186118

119+
(* ad-hoc rules for primitive data, eq and is_true *)
120+
121+
Module Export exports.
122+
Elpi derive.param1.trivial is_bool.
123+
End exports.
124+
125+
Definition is_uint63_inhab x : is_uint63 x. Proof. constructor. Defined.
126+
Register is_uint63_inhab as elpi.derive.is_uint63_inhab.
127+
128+
Definition is_float64_inhab x : is_float64 x. Proof. constructor. Defined.
129+
Register is_float64_inhab as elpi.derive.is_float64_inhab.
130+
131+
Definition is_pstring_inhab s : is_pstring s. Proof. constructor. Defined.
132+
Register is_pstring_inhab as elpi.derive.is_pstring_inhab.
187133

134+
Definition is_eq_inhab
135+
A (PA : A -> Type) (HA : trivial A PA) (x : A) (px: PA x) y (py : PA y) (eq_xy : x = y) :
136+
is_eq A PA x px y py eq_xy.
137+
Proof.
138+
revert py.
139+
case eq_xy; clear eq_xy y.
140+
intro py.
141+
rewrite <- (trivial_uniq A PA HA x px); clear px.
142+
rewrite <- (trivial_uniq A PA HA x py); clear py.
143+
apply (is_eq_refl A PA x (trivial_full A PA HA x)).
144+
Defined.
145+
Register is_eq_inhab as elpi.derive.is_eq_inhab.
146+
147+
Definition is_true_inhab b (H : is_bool b) p : is_is_true b H p :=
148+
is_eq_inhab bool is_bool is_bool_trivial b H true is_true p.
149+
Register is_true_inhab as elpi.derive.is_true_inhab.
150+
151+
152+
Elpi Accumulate derive.param1.trivial.db lp:{{
153+
154+
:before "param1:inhab:start"
155+
param1-inhab-db {{ lib:elpi.derive.is_uint63 }} {{ lib:elpi.derive.is_uint63_inhab }}.
156+
:before "param1:inhab:start"
157+
param1-inhab-db {{ lib:elpi.derive.is_float64 }} {{ lib:elpi.derive.is_float64_inhab }}.
158+
:before "param1:inhab:start"
159+
param1-inhab-db {{ lib:elpi.derive.is_pstring }} {{ lib:elpi.derive.is_pstring_inhab }}.
160+
:before "param1:inhab:start"
161+
param1-inhab-db {{ lib:elpi.derive.is_eq }} {{ lib:elpi.derive.is_eq_inhab }}.
162+
:before "param1:inhab:start"
163+
param1-inhab-db {{ lib:elpi.derive.is_true }} {{ lib:elpi.derive.is_true_inhab }}.
164+
165+
166+
:before "param1:inhab:start"
167+
param1-inhab-db
168+
{{ lib:elpi.derive.is_eq lp:A lp:PA lp:X lp:PX lp:Y lp:PY }}
169+
{{ lib:elpi.derive.is_eq_inhab lp:A lp:PA lp:QA lp:X lp:PX lp:Y lp:PY }} :- !,
170+
param1-trivial-db PA QA.
171+
172+
:before "param1:inhab:start"
173+
param1-inhab-db {{ lib:elpi.derive.is_is_true lp:B lp:PB }} R :- !,
174+
param1-inhab-db {{ lib:elpi.derive.is_eq lib:elpi.bool lib:elpi.derive.is_bool lp:B lp:PB lib:elpi.true lib:elpi.derive.is_true }} R.
175+
176+
}}.
177+
178+
179+
Definition is_uint63_trivial : trivial PrimInt63.int is_uint63 :=
180+
fun x => contracts _ is_uint63 x (is_uint63_inhab x)
181+
(fun y => match y with uint63 i => eq_refl end).
182+
Register is_uint63_trivial as elpi.derive.is_uint63_trivial.
183+
184+
Definition is_float64_trivial : trivial PrimFloat.float is_float64 :=
185+
fun x => contracts _ is_float64 x (is_float64_inhab x)
186+
(fun y => match y with float64 i => eq_refl end).
187+
Register is_float64_trivial as elpi.derive.is_float64_trivial.
188+
189+
Definition is_pstring_trivial : trivial lib:elpi.pstring is_pstring :=
190+
fun x => contracts _ is_pstring x (is_pstring_inhab x)
191+
(fun y => match y with pstring i => eq_refl end).
192+
Register is_pstring_trivial as elpi.derive.is_pstring_trivial.
193+
194+
Lemma is_eq_trivial A (PA : A -> Type) (HA : trivial A PA) (x : A) (px: PA x)
195+
y (py : PA y)
196+
: trivial (x = y) (is_eq A PA x px y py).
197+
Proof.
198+
intro p.
199+
apply (contracts (x = y) (is_eq A PA x px y py) p (is_eq_inhab A PA HA x px y py p)).
200+
revert py.
201+
case p; clear p y.
202+
rewrite <- (trivial_uniq _ _ HA x px). clear px.
203+
intros py.
204+
rewrite <- (trivial_uniq _ _ HA x py). clear py.
205+
intro v; case v; clear v.
206+
unfold is_eq_inhab.
207+
unfold trivial_full.
208+
unfold trivial_uniq.
209+
case (HA x); intros it def_it; compute.
210+
case (def_it it).
211+
reflexivity.
212+
Defined.
213+
Register is_eq_trivial as elpi.derive.is_eq_trivial.
214+
215+
Definition is_true_trivial b (H : is_bool b) : trivial (lib:elpi.is_true b) (is_is_true b H) :=
216+
is_eq_trivial bool is_bool is_bool_trivial b H true is_true.
217+
Register is_true_trivial as elpi.derive.is_true_trivial.
218+
219+
220+
Elpi Accumulate derive.param1.trivial.db lp:{{
221+
222+
:before "param1:trivial:start"
223+
param1-trivial-db {{ lib:elpi.derive.is_uint63 }} {{ lib:elpi.derive.is_uint63_trivial }}.
224+
:before "param1:trivial:start"
225+
param1-trivial-db {{ lib:elpi.derive.is_float64 }} {{ lib:elpi.derive.is_float64_trivial }}.
226+
:before "param1:trivial:start"
227+
param1-trivial-db {{ lib:elpi.derive.is_pstring }} {{ lib:elpi.derive.is_pstring_trivial }}.
228+
:before "param1:trivial:start"
229+
param1-trivial-db {{ lib:elpi.derive.is_eq }} {{ lib:elpi.derive.is_eq_trivial }}.
230+
:before "param1:trivial:start"
231+
param1-trivial-db {{ lib:elpi.derive.is_true }} {{ lib:elpi.derive.is_true_trivial }}.
232+
233+
234+
:before "param1:trivial:start"
235+
param1-trivial-db
236+
{{ lib:elpi.derive.is_eq lp:A lp:PA lp:X lp:PX lp:Y lp:PY }}
237+
{{ lib:elpi.derive.is_eq_trivial lp:A lp:PA lp:QA lp:X lp:PX lp:Y lp:PY }} :-
238+
param1-trivial-db PA QA.
239+
240+
:before "param1:trivial:start"
241+
param1-trivial-db {{ lib:elpi.derive.is_is_true lp:B lp:PB }} R :- !,
242+
param1-trivial-db {{ lib:elpi.derive.is_eq lib:elpi.bool lib:elpi.derive.is_bool lp:B lp:PB lib:elpi.true lib:elpi.derive.is_true }} R.
243+
244+
}}.
188245

189246
(* hook into derive *)
190247
Elpi Accumulate derive Db derive.param1.trivial.db.

theories/elpi.v.in

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,11 @@ Register Coq.Init.Datatypes.false as elpi.false.
4646
#[only="8.20"] Register Coq.Bool.Bool.reflect as elpi.reflect.
4747
#[only="8.20"] Register Coq.Bool.Bool.ReflectF as elpi.ReflectF.
4848
#[only="8.20"] Register Coq.Bool.Bool.ReflectT as elpi.ReflectT.
49+
#[only="8.20"] Register Coq.Init.Datatypes.is_true as elpi.is_true.
4950
#[skip="8.20"] Register Corelib.Init.Datatypes.reflect as elpi.reflect.
5051
#[skip="8.20"] Register Corelib.Init.Datatypes.ReflectF as elpi.ReflectF.
5152
#[skip="8.20"] Register Corelib.Init.Datatypes.ReflectT as elpi.ReflectT.
53+
#[skip="8.20"] Register Corelib.Init.Datatypes.is_true as elpi.is_true.
5254

5355
#[only="8.20"] From Coq Require PrimString.
5456
#[skip="8.20"] From Corelib Require PrimString.

0 commit comments

Comments
 (0)