aboutsummaryrefslogtreecommitdiffhomepage
path: root/engine
diff options
context:
space:
mode:
authorGravatar Pierre-Marie Pédrot <pierre-marie.pedrot@inria.fr>2016-10-12 21:14:07 +0200
committerGravatar Pierre-Marie Pédrot <pierre-marie.pedrot@inria.fr>2016-10-12 21:14:07 +0200
commit05ad4f49ac2203dd64dfec79a1fc62ee52115724 (patch)
tree920faae7946821c093345fd1804c40336bd9f1c4 /engine
parent8a6c792505160de4ba2123ef049ab45d28873e47 (diff)
parent0222f685ebdd55a1596d6689b96ebb86454ba1a7 (diff)
Merge branch 'v8.6'
Diffstat (limited to 'engine')
-rw-r--r--engine/ftactic.ml23
-rw-r--r--engine/proofview.ml43
-rw-r--r--engine/proofview.mli15
3 files changed, 62 insertions, 19 deletions
diff --git a/engine/ftactic.ml b/engine/ftactic.ml
index 588709873..aeaaea7e4 100644
--- a/engine/ftactic.ml
+++ b/engine/ftactic.ml
@@ -29,13 +29,28 @@ let bind (type a) (type b) (m : a t) (f : a -> b t) : b t = m >>= function
| Uniform x ->
(** We dispatch the uniform result on each goal under focus, as we know
that the [m] argument was actually dependent. *)
- Proofview.Goal.goals >>= fun l ->
- let ans = List.map (fun _ -> x) l in
+ Proofview.Goal.goals >>= fun goals ->
+ let ans = List.map (fun g -> (g,x)) goals in
Proofview.tclUNIT ans
- | Depends l -> Proofview.tclUNIT l
+ | Depends l ->
+ Proofview.Goal.goals >>= fun goals ->
+ Proofview.tclUNIT (List.combine goals l)
+ in
+ (* After the tactic has run, some goals which were previously
+ produced may have been solved by side effects. The values
+ attached to such goals must be discarded, otherwise the list of
+ result would not have the same length as the list of focused
+ goals, which is an invariant of the [Ftactic] module. It is the
+ reason why a goal is attached to each result above. *)
+ let filter (g,x) =
+ g >>= fun g ->
+ Proofview.Goal.unsolved g >>= function
+ | true -> Proofview.tclUNIT (Some x)
+ | false -> Proofview.tclUNIT None
in
Proofview.tclDISPATCHL (List.map f l) >>= fun l ->
- Proofview.tclUNIT (Depends (List.concat l))
+ Proofview.Monad.List.map_filter filter (List.concat l) >>= fun filtered ->
+ Proofview.tclUNIT (Depends filtered)
let goals = Proofview.Goal.goals >>= fun l -> Proofview.tclUNIT (Depends l)
let set_sigma r =
diff --git a/engine/proofview.ml b/engine/proofview.ml
index 1ebc857d8..d7fb65126 100644
--- a/engine/proofview.ml
+++ b/engine/proofview.ml
@@ -685,6 +685,21 @@ let unshelve l p =
let l = undefined p.solution l in
{ p with comb = p.comb@l }
+let mark_in_evm ~goal evd content =
+ let info = Evd.find evd content in
+ let info =
+ if goal then
+ { info with Evd.evar_source = match info.Evd.evar_source with
+ | _, (Evar_kinds.VarInstance _ | Evar_kinds.GoalEvar) as x -> x
+ | loc,_ -> loc,Evar_kinds.GoalEvar }
+ else info
+ in
+ let info = match Evd.Store.get info.Evd.evar_extra typeclass_resolvable with
+ | None -> { info with Evd.evar_extra = Evd.Store.set info.Evd.evar_extra typeclass_resolvable () }
+ | Some () -> info
+ in
+ Evd.add evd content info
+
let with_shelf tac =
let open Proof in
Pv.get >>= fun pv ->
@@ -697,8 +712,11 @@ let with_shelf tac =
let fgoals = Evd.future_goals solution in
let pgoal = Evd.principal_future_goal solution in
let sigma = Evd.restore_future_goals sigma fgoals pgoal in
- Pv.set { npv with shelf; solution = sigma } >>
- tclUNIT (CList.rev_append gls' gls, ans)
+ (* Ensure we mark and return only unsolved goals *)
+ let gls' = undefined sigma (CList.rev_append gls' gls) in
+ let sigma = CList.fold_left (mark_in_evm ~goal:false) sigma gls' in
+ let npv = { npv with shelf; solution = sigma } in
+ Pv.set npv >> tclUNIT (gls', ans)
(** [goodmod p m] computes the representative of [p] modulo [m] in the
interval [[0,m-1]].*)
@@ -929,6 +947,8 @@ module Unsafe = struct
{ step with comb = step.comb @ gls }
end
+ let tclSETENV = Env.set
+
let tclGETGOALS = Comb.get
let tclSETGOALS = Comb.set
@@ -943,20 +963,13 @@ module Unsafe = struct
{ p with solution = Evd.reset_future_goals p.solution }
let mark_as_goal evd content =
- let info = Evd.find evd content in
- let info =
- { info with Evd.evar_source = match info.Evd.evar_source with
- | _, (Evar_kinds.VarInstance _ | Evar_kinds.GoalEvar) as x -> x
- | loc,_ -> loc,Evar_kinds.GoalEvar }
- in
- let info = match Evd.Store.get info.Evd.evar_extra typeclass_resolvable with
- | None -> { info with Evd.evar_extra = Evd.Store.set info.Evd.evar_extra typeclass_resolvable () }
- | Some () -> info
- in
- Evd.add evd content info
+ mark_in_evm ~goal:true evd content
let advance = advance
+ let mark_as_unresolvable p gl =
+ { p with solution = mark_in_evm ~goal:false p.solution gl }
+
let typeclass_resolvable = typeclass_resolvable
end
@@ -1129,6 +1142,10 @@ module Goal = struct
in
tclUNIT (CList.map_filter map step.comb)
+ let unsolved { self=self } =
+ tclEVARMAP >>= fun sigma ->
+ tclUNIT (not (Option.is_empty (advance sigma self)))
+
(* compatibility *)
let goal { self=self } = self
diff --git a/engine/proofview.mli b/engine/proofview.mli
index bc68f11ff..725445251 100644
--- a/engine/proofview.mli
+++ b/engine/proofview.mli
@@ -326,8 +326,9 @@ val unshelve : Goal.goal list -> proofview -> proofview
(** [depends_on g1 g2 sigma] checks if g1 occurs in the type/ctx of g2 *)
val depends_on : Evd.evar_map -> Goal.goal -> Goal.goal -> bool
-(** [with_shelf tac] executes [tac] and returns its result together with the set
- of goals shelved by [tac]. The current shelf is unchanged. *)
+(** [with_shelf tac] executes [tac] and returns its result together with
+ the set of goals shelved by [tac]. The current shelf is unchanged
+ and the returned list contains only unsolved goals. *)
val with_shelf : 'a tactic -> (Goal.goal list * 'a) tactic
(** If [n] is positive, [cycle n] puts the [n] first goal last. If [n]
@@ -409,6 +410,9 @@ module Unsafe : sig
(** Like {!tclEVARS} but also checks whether goals have been solved. *)
val tclEVARSADVANCE : Evd.evar_map -> unit tactic
+ (** Set the global environment of the tactic *)
+ val tclSETENV : Environ.env -> unit tactic
+
(** [tclNEWGOALS gls] adds the goals [gls] to the ones currently
being proved, appending them to the list of focused goals. If a
goal is already solved, it is not added. *)
@@ -431,6 +435,9 @@ module Unsafe : sig
and makes it unresolvable for type classes. *)
val mark_as_goal : Evd.evar_map -> Evar.t -> Evd.evar_map
+ (** Make an evar unresolvable for type classes. *)
+ val mark_as_unresolvable : proofview -> Evar.t -> proofview
+
(** [advance sigma g] returns [Some g'] if [g'] is undefined and is
the current avatar of [g] (for instance [g] was changed by [clear]
into [g']). It returns [None] if [g] has been (partially)
@@ -518,6 +525,10 @@ module Goal : sig
FIXME: encapsulate the level in an existential type. *)
val goals : ([ `LZ ], 'r) t tactic list tactic
+ (** [unsolved g] is [true] if [g] is still unsolved in the current
+ proof state. *)
+ val unsolved : ('a, 'r) t -> bool tactic
+
(** Compatibility: avoid if possible *)
val goal : ([ `NF ], 'r) t -> Evar.t