Skip to content

Commit 2796969

Browse files
committed
instance attribute
1 parent f4b1f1e commit 2796969

File tree

10 files changed

+70
-37
lines changed

10 files changed

+70
-37
lines changed

lambdap.elpi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ pred msolve o:list sealed-goal.
3434
% [lp.sig S T] Gives the type of a symbol
3535
external pred lp.sig i:symbol, o:term.
3636

37+
% [lp.tc-instances L] Gives the list of type class instances
38+
external pred lp.tc-instances o:list symbol.
39+
40+
% [lp.tc? S] Tells if S is a type class
41+
external pred lp.tc? i:symbol.
42+
3743
% [lp.term->string T S] Pretty prints a term T to the string S
3844
external pred lp.term->string i:term, o:string.
3945

src/core/sig_state.ml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ let dummy : sig_state =
4646
[p], strategy [st], name [x], type [a], implicit arguments [impl] and
4747
optional definition [def]. This new symbol is returned too. *)
4848
let add_symbol : sig_state -> expo -> prop -> match_strat
49-
-> bool -> strloc -> term -> bool list -> bool -> term option ->
49+
-> bool -> strloc -> term -> bool list -> bool -> bool -> term option ->
5050
sig_state * sym =
51-
fun ss expo prop mstrat opaq id typ impl tc def ->
51+
fun ss expo prop mstrat opaq id typ impl tc tci def ->
5252
let sym =
5353
Sign.add_symbol ss.signature expo prop mstrat opaq id
5454
(cleanup typ) impl in
5555
if tc then Sign.add_tc ss.signature sym;
56+
if tci then Sign.add_tc_inst ss.signature sym;
5657
begin
5758
match def with
5859
| Some t -> sym.sym_def := Some (cleanup t)

src/handle/command.ml

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,19 @@ let handle_require_as : compiler -> sig_state -> p_path -> p_ident ->
8080

8181
(** [handle_modifiers ms] verifies that the modifiers in [ms] are compatible.
8282
If so, they are returned as a tuple. Otherwise, it fails. *)
83-
let handle_modifiers : p_modifier list -> prop * expo * match_strat * bool =
83+
let handle_modifiers : p_modifier list -> prop * expo * match_strat * bool * bool =
8484
fun ms ->
85-
let rec get_modifiers ((props, expos, strats,tc) as acc) = function
85+
let rec get_modifiers ((props, expos, strats,tc,tci) as acc) = function
8686
| [] -> acc
87-
| {elt=P_typeclass;_}::ms -> get_modifiers (props, expos, strats,true) ms
88-
| {elt=P_prop _;_} as p::ms -> get_modifiers (p::props, expos, strats,tc) ms
89-
| {elt=P_expo _;_} as e::ms -> get_modifiers (props, e::expos, strats,tc) ms
87+
| {elt=P_typeclass;_}::ms -> get_modifiers (props, expos, strats,true, tci) ms
88+
| {elt=P_typeclass_instance;_}::ms -> get_modifiers (props, expos, strats,tc, true) ms
89+
| {elt=P_prop _;_} as p::ms -> get_modifiers (p::props, expos, strats,tc,tci) ms
90+
| {elt=P_expo _;_} as e::ms -> get_modifiers (props, e::expos, strats,tc,tci) ms
9091
| {elt=P_mstrat _;_} as s::ms ->
91-
get_modifiers (props, expos, s::strats,tc) ms
92+
get_modifiers (props, expos, s::strats,tc,tci) ms
9293
| {elt=P_opaq;_}::ms -> get_modifiers acc ms
9394
in
94-
let props, expos, strats, tc = get_modifiers ([],[],[],false) ms in
95+
let props, expos, strats, tc, tci = get_modifiers ([],[],[],false,false) ms in
9596
let prop =
9697
match props with
9798
| [{elt=P_prop (Assoc b);_};{elt=P_prop Commu;_}]
@@ -120,7 +121,7 @@ let handle_modifiers : p_modifier list -> prop * expo * match_strat * bool =
120121
| [] -> Eager
121122
| _ -> assert false
122123
in
123-
(prop, expo, strat, tc)
124+
(prop, expo, strat, tc, tci)
124125

125126
(** [check_rule ss syms r] checks rule [r] and returns the head symbol of the
126127
lhs and the rule itself. *)
@@ -164,7 +165,7 @@ let handle_inductive_symbol : sig_state -> expo -> prop -> match_strat
164165
end;
165166
(* Actually add the symbol to the signature and the state. *)
166167
Console.out 2 (Color.red "symbol %a : %a") uid name term typ;
167-
let r = add_symbol ss expo prop mstrat false id typ impl false None in
168+
let r = add_symbol ss expo prop mstrat false id typ impl false false None in
168169
sig_state := fst r; r
169170

170171
(** Representation of a yet unchecked proof. The structure is initialized when
@@ -282,9 +283,11 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
282283

283284
| P_inductive(ms, params, p_ind_list) ->
284285
(* Check modifiers. *)
285-
let (prop, expo, mstrat,tc) = handle_modifiers ms in
286+
let (prop, expo, mstrat,tc,tci) = handle_modifiers ms in
286287
if tc then
287288
fatal pos "Property typeclass cannot be used on inductive types.";
289+
if tci then
290+
fatal pos "Property instance cannot be used on inductive types.";
288291
if prop <> Defin then
289292
fatal pos "Property modifiers cannot be used on inductive types.";
290293
if mstrat <> Eager then
@@ -351,7 +354,8 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
351354
(* Recursors are declared after the types and constructors. *)
352355
let pos = after (end_pos pos) in
353356
let id = Pos.make pos rec_name in
354-
let r = add_symbol ss expo Defin Eager false id rec_typ [] false None
357+
let r =
358+
add_symbol ss expo Defin Eager false id rec_typ [] false false None
355359
in sig_state := fst r; r
356360
in
357361
(ss, rec_sym::rec_sym_list)
@@ -389,7 +393,7 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
389393
| _ -> ()
390394
end;
391395
(* Verify modifiers. *)
392-
let prop, expo, mstrat, tc = handle_modifiers p_sym_mod in
396+
let prop, expo, mstrat, tc, tci = handle_modifiers p_sym_mod in
393397
let opaq = List.exists Syntax.is_opaq p_sym_mod in
394398
let pdata_prv = expo = Privat || (p_sym_def && opaq) in
395399
(match p_sym_def, opaq, prop, mstrat with
@@ -494,7 +498,7 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
494498
Console.out 2 (Color.red "symbol %a : %a") uid id term a;
495499
wrn pe.pos "Proof admitted.";
496500
let t = Option.map (fun t -> t.elt) t in
497-
fst (add_symbol ss expo prop mstrat opaq p_sym_nam a impl tc t)
501+
fst (add_symbol ss expo prop mstrat opaq p_sym_nam a impl tc tci t)
498502
| P_proof_end ->
499503
(* Check that the proof is indeed finished. *)
500504
if not (finished ps) then
@@ -504,7 +508,7 @@ let get_proof_data : compiler -> sig_state -> p_command -> cmd_output =
504508
Option.map (fun m -> unfold (mk_Meta(m,[||]))) ps.proof_term in
505509
(* Add the symbol in the signature. *)
506510
Console.out 2 (Color.red "symbol %a : %a") uid id term a;
507-
fst (add_symbol ss expo prop mstrat opaq p_sym_nam a impl tc d)
511+
fst (add_symbol ss expo prop mstrat opaq p_sym_nam a impl tc tci d)
508512
in
509513
(* Create the proof state. *)
510514
let pdata_state =

src/handle/elpi_handle.ml

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ open Elpi.API
22
open Core
33
open Elpi_lambdapi
44

5+
let ss : Sig_state.t State.component =
6+
State.declare ~name:"elpi:ss"
7+
~pp:(fun _fmt _ -> ()) ~init:(fun () -> Sig_state.dummy) ~start:(fun x -> x)
58

69
let goalc = RawData.Constants.declare_global_symbol "goal"
710
let ofc = RawData.Constants.declare_global_symbol "of"
@@ -75,6 +78,23 @@ pred msolve o:list sealed-goal.
7578
(fun s _ ~depth:_ -> !: (Timed.(!) s.Term.sym_type))),
7679
DocAbove);
7780

81+
MLCode(Pred("lp.tc-instances",
82+
Out(list sym,"L",
83+
Read (ContextualConversion.unit_ctx, "Gives the list of type class instances")),
84+
(fun _ ~depth:_ _ _ state ->
85+
let s = (State.get ss state).Sig_state.signature in
86+
!: ((Timed.(!) s.Sign.sign_tc_inst) |> Term.SymSet.elements))),
87+
DocAbove);
88+
89+
MLCode(Pred("lp.tc?",
90+
In(sym,"S",
91+
Read (ContextualConversion.unit_ctx, "Tells if S is a type class")),
92+
(fun sym ~depth:_ _ _ state ->
93+
let s = (State.get ss state).Sig_state.signature in
94+
if ((Timed.(!) s.Sign.sign_tc) |> Term.SymSet.mem sym) then ()
95+
else raise No_clause)),
96+
DocAbove);
97+
7898
MLCode(Pred("lp.term->string",
7999
In(term,"T",
80100
Out(string,"S",
@@ -188,6 +208,13 @@ let tc_metas_of_term : Sig_state.t -> Term.ctxt -> Term.term -> Term.meta list =
188208

189209
let scope_ref : (Parsing.Syntax.p_term -> Term.term * (int * string) list) ref = ref (fun _ -> assert false)
190210

211+
(* we set the state, Elpi.API.Qery lacks this function *)
212+
let hack s c = { c with Conversion.embed =
213+
fun ~depth state x ->
214+
let state = State.set ss state s in
215+
c.Conversion.embed ~depth state x
216+
}
217+
191218
let solve_tc : ?scope:(Parsing.Syntax.p_term -> Term.term * (int * string) list) -> Sig_state.t -> Common.Pos.popt -> Term.problem -> Term.ctxt ->
192219
Term.term * Term.term -> Term.term * Term.term =
193220
fun ?scope ss pos _pb ctxt (t,ty) ->
@@ -213,7 +240,7 @@ let solve_tc : ?scope:(Parsing.Syntax.p_term -> Term.term * (int * string) list)
213240
let open Elpi.API.Query in
214241
let open Elpi.API.BuiltInData in
215242
compile prog pos
216-
(Query { predicate; arguments = (D(list goal,tc,N)) }) in
243+
(Query { predicate; arguments = (D(hack ss (list goal),tc,N)) }) in
217244

218245
if not (Elpi.API.Compile.static_check
219246
~checker:(Elpi.Builtin.default_checker ()) query) then

src/handle/tactic.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ let add_axiom : Sig_state.t -> popt -> meta -> Sig_state.t =
3838
in
3939
let id = Pos.make pos name in
4040
Sig_state.add_symbol
41-
ss Public Defin Eager true id !(m.meta_type) [] false None
41+
ss Public Defin Eager true id !(m.meta_type) [] false false None
4242
in
4343
(* Create the value which will be substituted for the metavariable. This
4444
value is [sym x0 ... xn] where [xi] are variables that will be

src/parsing/lpLexer.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ type token =
5656
| INDUCTIVE
5757
| INFIX
5858
| INJECTIVE
59+
| INSTANCE
5960
| LET
6061
| NOTATION
6162
| OPAQUE
@@ -221,6 +222,7 @@ let rec token lb =
221222
| "inductive" -> INDUCTIVE
222223
| "infix" -> INFIX
223224
| "injective" -> INJECTIVE
225+
| "instance" -> INSTANCE
224226
| "left" -> SIDE(Pratter.Left)
225227
| "let" -> LET
226228
| "notation" -> NOTATION

src/parsing/lpParser.mly

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
%token INDUCTIVE
5050
%token INFIX
5151
%token INJECTIVE
52+
%token INSTANCE
5253
%token LET
5354
%token NOTATION
5455
%token OPAQUE
@@ -207,6 +208,7 @@ modifier:
207208
| PROTECTED { make_pos $sloc (P_expo Term.Protec) }
208209
| SEQUENTIAL { make_pos $sloc (P_mstrat Term.Sequen) }
209210
| TYPECLASS { make_pos $sloc P_typeclass }
211+
| INSTANCE { make_pos $sloc P_typeclass_instance }
210212

211213
uid: s=UID { make_pos $sloc s}
212214

src/parsing/syntax.ml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ type p_modifier_aux =
235235
| P_prop of Term.prop (** symbol properties: constant, definable, ... *)
236236
| P_opaq (** opacity *)
237237
| P_typeclass
238+
| P_typeclass_instance
238239

239240
type p_modifier = p_modifier_aux loc
240241

tcsolver.elpi

Lines changed: 6 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
msolve L :-
2-
compile_all [{{eqdec}}] Cl,
2+
compile_all Cl,
33
Cl => std.forall L (open tc).
44

55
pred open i:(term -> term -> prop), i:sealed-goal.
@@ -12,15 +12,9 @@ open P (seal (goal Ctx Ty Wit)) :-
1212
:index(_ 4)
1313
pred tc o:term, o:term.
1414

15-
pred is_typeclass o:term.
16-
is_typeclass {{eqdec}}.
17-
18-
pred instances o:term o:list term.
19-
instances {{eqdec}} [{{bool_eqdec}}, {{nat_eqdec}}, {{pair_eqdec}}].
20-
2115
pred compile i:term, i:list prop, i:term, o:prop.
2216
compile (prod (appl T U) F) TODO H (pi x\ C x) :-
23-
is_typeclass T,
17+
T = symb S, lp.tc? S,
2418
!,
2519
pi x\
2620
compile (F x) [tc (appl T U) x |TODO] (appl H x) (C x).
@@ -32,13 +26,9 @@ compile (prod _ F) TODO H (pi x\ C x) :-
3226

3327
compile End TODO HD (tc End HD :- TODO).
3428

35-
pred compile_all i:list term, o:list prop.
36-
compile_all Refs Props :-
37-
std.map Refs instances LList,
38-
std.flatten LList Candidates,
29+
pred compile_all o:list prop.
30+
compile_all Props :-
31+
lp.tc-instances Candidates,
3932
std.map Candidates
40-
(cand\claus\ sigma T\ sigma N\
41-
cand = (symb N),
42-
lp.sig N T,
43-
compile T [] cand claus)
33+
(N\claus\ sigma T\ lp.sig N T, compile T [] (symb N) claus)
4434
Props.

tests/OK/elpitest.lp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ symbol mk_Pair [i] [j] : T i → T j → Pair i j;
2424
symbol pair : UUU;
2525
rule T (pair $i $j) ↪ Pair $i $j;
2626

27-
/* instance */ symbol bool_eqdec : eqdec boolmk_eqdec eq_bool /* p */;
28-
/* instance */ symbol nat_eqdec : eqdec natmk_eqdec eq_nat /* p */;
29-
/* instance */ symbol pair_eqdec : Π i j, eqdec ieqdec jeqdec (pair i j);
27+
instance symbol bool_eqdec : eqdec boolmk_eqdec eq_bool /* p */;
28+
instance symbol nat_eqdec : eqdec natmk_eqdec eq_nat /* p */;
29+
instance symbol pair_eqdec : Π i j, eqdec ieqdec jeqdec (pair i j);
3030
/* ≔ mk_eqdec eq_nat ; */
3131

3232
type λ b , true == b;

0 commit comments

Comments
 (0)