Skip to content

Commit 1fbc593

Browse files
authored
Merge pull request #646 from FissoreD/tc-str2gr-not-in-cache
TC str2gr conversion not in cache + adapt solve_TC wrt coq hook
2 parents a61d475 + d082ec1 commit 1fbc593

File tree

4 files changed

+115
-23
lines changed

4 files changed

+115
-23
lines changed

apps/tc/src/coq_elpi_class_tactics_takeover.ml

+47-23
Original file line numberDiff line numberDiff line change
@@ -1571,37 +1571,65 @@ let elpi_fails program_name =
15711571
"Please report this inconvenience to the authors of the program."
15721572
]))
15731573

1574+
module type M = sig
1575+
type elt
1576+
type t
1577+
val empty : t
1578+
val diff : t -> t -> t
1579+
val union : t -> t -> t
1580+
val add : elt -> t -> t
1581+
val gr2elt : Names.GlobRef.t -> elt
1582+
val mem : elt -> t -> bool
1583+
val of_qualid_list : Libnames.qualid list -> t
1584+
1585+
end
1586+
1587+
(* Set of overridden class *)
1588+
module OSet : M = struct
1589+
module M = GRSet
1590+
1591+
type t = M.t
1592+
type elt = M.elt
1593+
let empty = M.empty
1594+
let diff = M.diff
1595+
let union = M.union
1596+
let add = M.add
1597+
let mem = M.mem
1598+
let gr2elt (x: Names.GlobRef.t) : elt = x
1599+
1600+
let of_qualid_list (x: Libnames.qualid list) : t =
1601+
let add s x = add (Coq_elpi_utils.locate_simple_qualid x) s in
1602+
List.fold_left add empty x
1603+
end
15741604

15751605
module Modes = struct
15761606

15771607
(** override_mode *)
15781608
type omode =
1579-
| AllButFor of GRSet.t
1580-
| Only of GRSet.t
1609+
| AllButFor of OSet.t
1610+
| Only of OSet.t
15811611

15821612
type action =
15831613
| Set of omode
1584-
| Add of Libnames.qualid list
1585-
| Rm of Libnames.qualid list
1614+
| Add of OSet.t
1615+
| Rm of OSet.t
15861616

15871617
let omodes = ref (CSMap.empty : omode CSMap.t)
15881618

15891619
let create_solver_omode solver =
1590-
omodes := CSMap.add solver (Only GRSet.empty) !omodes
1620+
omodes := CSMap.add solver (Only OSet.empty) !omodes
15911621

15921622
let takeover (qname, new_mode,c) =
15931623
let name = qname2str qname in
15941624
if c then create_solver_omode name else
1595-
let add_str x = GRSet.add (str2gr x) in
1596-
let grl2set grl = List.fold_right add_str grl GRSet.empty in
15971625
let old_mode = CSMap.find name !omodes in
15981626
let new_mode =
15991627
match old_mode, new_mode with
16001628
| _, Set(mode) -> mode
1601-
| AllButFor s, Add grl -> AllButFor (GRSet.diff s (grl2set grl))
1602-
| AllButFor s, Rm grl -> AllButFor (GRSet.union s (grl2set grl))
1603-
| Only s, Add grl -> Only (GRSet.union s (grl2set grl))
1604-
| Only s, Rm grl -> Only (GRSet.diff s (grl2set grl))
1629+
| AllButFor s, Add grl -> AllButFor (OSet.diff s grl)
1630+
| AllButFor s, Rm grl -> AllButFor (OSet.union s grl)
1631+
| Only s, Add grl -> Only (OSet.union s grl)
1632+
| Only s, Rm grl -> Only (OSet.diff s grl)
16051633
in
16061634
omodes := CSMap.set name new_mode !omodes
16071635

@@ -1627,11 +1655,11 @@ module Solver = struct
16271655
match Coq_elpi_vernacular.Interp.run ~static_check:false cprogram (`Fun query) with
16281656
| API.Execute.Success solution ->
16291657
let sigma, sub_goals, to_shelve = Coq_elpi_HOAS.solution2evd ~eta_contract_solution:true sigma solution (Evar.Set.of_list goals) in
1630-
let sigma = Evd.shelve sigma (sub_goals @ to_shelve) in
1658+
let sigma = Evd.shelve sigma sub_goals in
16311659
sub_goals = [], sigma
16321660
| API.Execute.NoMoreSteps -> CErrors.user_err Pp.(str "elpi run out of steps")
16331661
| API.Execute.Failure -> elpi_fails program
1634-
| exception (Coq_elpi_utils.LtacFail (level, msg)) -> elpi_fails program
1662+
| exception (Coq_elpi_utils.LtacFail (level, msg)) -> raise Not_found
16351663
}
16361664

16371665
type action =
@@ -1643,9 +1671,7 @@ module Solver = struct
16431671
let ei = Evd.find_undefined sigma i in
16441672
let ty = Evd.evar_concl ei in
16451673
match Typeclasses.class_of_constr env sigma ty with
1646-
| Some (_,(((cl: typeclass),_),_)) ->
1647-
let cl_impl = cl.Typeclasses.cl_impl in
1648-
GRSet.mem cl_impl classes
1674+
| Some (_,((cl,_),_)) -> OSet.mem (OSet.gr2elt cl.cl_impl) classes
16491675
| None -> default
16501676

16511677
let covered omode env sigma s =
@@ -1668,20 +1694,18 @@ end
16681694

16691695

16701696
let set_solver_mode kind qname (l: Libnames.qualid list) =
1697+
let l = OSet.of_qualid_list l in
16711698
let cache_solver_mode = Modes.cache_solver_mode in
1672-
let empty = GRSet.empty in
16731699
match kind with
16741700
| AAdd -> Lib.add_leaf (cache_solver_mode (qname, Add l, false))
16751701
| ARm -> Lib.add_leaf (cache_solver_mode (qname, Rm l, false))
1676-
| AAll -> Lib.add_leaf (cache_solver_mode (qname, Set (AllButFor empty), false))
1677-
| ANone-> Lib.add_leaf (cache_solver_mode (qname, Set (Only empty), false))
1678-
| ASet -> let set = ref empty in
1679-
List.iter (fun x -> set := GRSet.add (str2gr x) !set) l;
1680-
Lib.add_leaf (cache_solver_mode (qname, Set (Only !set), false))
1702+
| AAll -> Lib.add_leaf (cache_solver_mode (qname, Set (AllButFor OSet.empty), false))
1703+
| ANone-> Lib.add_leaf (cache_solver_mode (qname, Set (Only OSet.empty), false))
1704+
| ASet -> Lib.add_leaf (cache_solver_mode (qname, Set (Only l), false))
16811705

16821706
let solver_register l =
16831707
Lib.add_leaf (Solver.cache_solver (l, Create));
1684-
Lib.add_leaf (Modes.cache_solver_mode (l, Add [], true))
1708+
Lib.add_leaf (Modes.cache_solver_mode (l, Add OSet.empty, true))
16851709

16861710
let solver_activate l = Lib.add_leaf (Solver.cache_solver (l, Activate))
16871711

apps/tc/tests/lemma_with_max_impl.v

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
From elpi.apps Require Import tc.
2+
3+
Class A (n : nat).
4+
Instance a : A 0 := {}.
5+
6+
Class B (n : nat).
7+
8+
Class C (n : nat).
9+
Instance b x: C x := {}.
10+
11+
Lemma foo: forall (x n: nat) `{A x} `{C n}, True -> B n. Admitted.
12+
Lemma bar: forall (n: nat) `{A n}, True -> B n. Admitted.
13+
14+
Goal exists n, B n.
15+
Proof.
16+
eexists.
17+
(* Note: `{A x} and `{C n} are solved with x = 0, n remains a hole *)
18+
(* Moreover, True remains as active goal + a shelved goal remain for n *)
19+
refine (foo _ _ _).
20+
auto.
21+
Unshelve.
22+
constructor.
23+
Qed.
24+
25+
Goal exists x, B x.
26+
Proof.
27+
eexists.
28+
(* Note: `{A x} is solved with x = 0 *)
29+
refine (bar _ _).
30+
auto.
31+
Qed.
32+
33+
34+
Goal exists x, C x.
35+
Proof.
36+
eexists.
37+
apply _.
38+
Unshelve.
39+
constructor.
40+
Qed.
41+
42+
Class Decision (P : Type).
43+
44+
Goal forall (A : Type) (P1: A -> Prop),
45+
exists (P : A -> A -> A -> Prop), forall z y , (forall x, Decision (P1 x))
46+
-> forall x, Decision (P z y x).
47+
Proof.
48+
eexists; intros.
49+
apply _.
50+
Unshelve.
51+
auto.
52+
Qed.
53+
54+
Elpi Tactic A.
55+
Elpi Accumulate lp:{{
56+
msolve L _ :- coq.ltac.fail _ "[TC] fail to solve" L.
57+
}}.
58+
Goal exists n, B n.
59+
eexists.
60+
Fail apply _.
61+
Abort.
62+
63+

apps/tc/tests/test_import/f1.v

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
From elpi.apps Require Export tc.
2+
From Coq Require Export Morphisms.
3+
4+
Elpi TC Solver Override TC.Solver Rm Proper ProperProxy.

apps/tc/tests/test_import/f2.v

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
From elpi.apps.tc.tests.test_import Require Import f1.

0 commit comments

Comments
 (0)