(************************************************************************) (* * The Rocq Prover / The Rocq Development Team *) (* v * Copyright INRIA, CNRS and contributors *) (* <O___,, * (see version control and CREDITS file for authors & dates) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************)
(** This files defines the basic mechanism of proofs: the [proofview] typeisthestatewhichtacticsmanipulate(aglobalstatefor existentialvariables,togetherwiththelistofgoals),andthetype ['atactic]isthe(abstract)typeoftacticsmodifyingtheproof
state and returning a value of type ['a]. *)
open EConstr
(** Main state of tactics *) type proofview
(** Returns a stylised view of a proofview for use by, for instance,
ide-s. *) (* spiwack: the type of [proofview] will change as we push more refinedfunctionstoide-s.Thiswouldbebetterthanspawninga
new nearly identical function every time. Hence the generic name. *) (* In this version: returns the list of focused goals together with
the [evar_map] context. *) val proofview : proofview -> Evar.t list * Evd.evar_map
(** {6 Starting and querying a proof view} *)
(** Abstract representation of the initial goals of a proof. *) type entry
(** Initialises a proofview, the main argument is a list of environments(includinga[named_context]whichareusedas hypotheses)pairwithconclusiontypes,creatingaccordinglymany initialgoals.Becauseaproofdoesnotnecessarilystartsinan empty[evar_map](indeedaproofcanbetriggeredbyanincomplete pretyping),[init]takesanadditionalargumenttorepresentthe
initial [evar_map]. *) val init : Evd.evar_map -> (Environ.env * types) list -> entry * proofview
(** A [telescope] is a list of environment and conclusion like in {!init},exceptthateachelementmaydependontheprevious goals.Thetelescopepassesthegoalsintheformofa [Term.constr]whichrepresentsthegoalasan[evar].The
[evar_map] is threaded in state passing style. *) type telescope =
| TNil of Evd.evar_map
| TCons of Environ.env * Evd.evar_map * types * (Evd.evar_map -> constr -> telescope)
(** Like {!init}, but goals are allowed to be dependent on one another.Dependenciesbetweengoalsisrepresentedwiththetype [telescope]insteadof[list].Notethatthefirst[evar_map]of thetelescopeplaystheroleofthe[evar_map]argumentin
[init]. *) val dependent_init : telescope -> entry * proofview
(** [finished pv] is [true] if and only if [pv] is complete. That is, ifithasanemptylistoffocusedgoals.Therecouldstillbe
unsolved subgoals, but they would then be out of focus. *) val finished : proofview -> bool
(** Returns the current [evar] state. *) val return : proofview -> Evd.evar_map
val partial_proof : entry -> proofview -> constr list val initial_goals : entry -> (Environ.named_context_val * constr * types) list
(** goal <-> goal_with_state *)
val with_empty_state :
Proofview_monad.goal -> Proofview_monad.goal_with_state val drop_state :
Proofview_monad.goal_with_state -> Proofview_monad.goal val goal_with_state :
Proofview_monad.goal -> Proofview_monad.StateStore.t ->
Proofview_monad.goal_with_state
(** {6 Focusing commands} *)
(** A [focus_context] represents the part of the proof view which has beenremovedbyafocusingaction,itcanbeusedtounfocuslater
on. *) type focus_context
(** Returns a stylised view of a focus_context for use by, for
instance, ide-s. *) (* spiwack: the type of [focus_context] will change as we push more refinedfunctionstoide-s.Thiswouldbebetterthanspawninga
new nearly identical function every time. Hence the generic name. *) (* In this version: the goals in the context, as a "zipper" (the first
list is in reversed order). *) val focus_context : Evd.evar_map -> focus_context -> Evar.t list * Evar.t list
(** [focus i j] focuses a proofview on the goals from index [i] to index[j](inclusive,goalsareindexedfrom[1]).I.e.goals number[i]to[j]becometheonlyfocusedgoalsofthereturned proofview.Itreturnsthefocusedproofview,andacontextfor
the focus stack. *) val focus : int -> int -> proofview -> proofview * focus_context
(** Unfocuses a proofview with respect to a context. *) val unfocus : focus_context -> proofview -> proofview
(** {6 The tactic monad} *)
(** - Tactics are objects which apply a transformation to all the subgoalsofthecurrentviewatthesametime.Byoppositionto theoldvisionofapplyingittoasinglegoal.Itallowstactics suchas[shelve_unifiable],tacticstoreorderthefocusedgoals, orglobalautomationtacticfordependentsubgoals(instantiating anevarhasinfluencesontheothergoalsoftheproofin progress,notbeingabletotakethatintoaccountcausesthe currenteautotactictofailonsomeinstanceswhereitcould succeed).Anotherbenefitisthatitispossibletowritetactics thatcanbeexecutedeveniftherearenofocusedgoals. -Tacticsformamonad['atactic],inasenseatacticcanbe seenasafunction(withoutargument)whichreturnsavalueof type'aandmodifiestheenvironment(inourcase:theview). Tacticsofcoursehavearguments,butthesearegivenatthe meta-levelasOCamlfunctions.Mosttacticsinthesenseweare usedtoreturn[()],thatisnoreallyinterestingvalues.But somemightpassinformationaround.ThetacticsseeninRocq's Ltacare(fornowatleast)only[unittactic],thereturnvalues arekeptfortheOCamltoolkit.Theoperationorthemonadare [Proofview.tclUNIT](whichisthe"return"ofthetacticmonad) [Proofview.tclBIND](whichisthe"bind")and[Proofview.tclTHEN] (whichisaspecializedbindonunit-returningtactics). -Tacticshavesupportforfull-backtracking.Tacticscanbeseen havingmultiplesuccess:ifafterreturningthefirstsuccessa failureisencountered,thetacticcanbacktrackanduseasecond successifavailable.Thestateisbacktrackedtoitsprevious value,exceptthenon-logicalstatedefinedinthe{!NonLogical} modulebelow.
*)
(** The abstract type of tactics *) type +'a tactic
(** Applies a tactic to the current proofview. Returns a tuple [a,pv,(b,sh,gu)]where[a]isthereturnvalueofthetactic,[pv] istheupdatedproofview,[b]abooleanwhichis[true]ifthe tactichasnotdoneanyactionconsideredunsafe(suchas admittingalemma),[sh]isthelistofgoalswhichhavebeen shelvedbythetactic,and[gu]thelistofgoalsonwhichthe tactichasgivenup.Incaseofmultiplesuccessthefirstoneis selected.Ifthereisnosuccess,failswith
{!Logic_monad.TacticFailure}*) val apply
: name:Names.Id.t
-> poly:bool
-> Environ.env
-> 'a tactic
-> proofview
-> 'a * proofview
* Environ.env
* bool
* Proofview_monad.Info.tree
(** {7 Monadic primitives} *)
(** Unit of the tactic monad. *) val tclUNIT : 'a -> 'a tactic
(** Bind operation of the tactic monad. *) val tclBIND : 'a tactic -> ('a -> 'b tactic) -> 'b tactic
(** Interprets the ";" (semicolon) of Ltac. As a monadic operation,
it's a specialized "bind". *) val tclTHEN : unit tactic -> 'a tactic -> 'a tactic
(** [tclIGNORE t] has the same operational content as [t], but drops
the returned value. *) val tclIGNORE : 'a tactic -> unit tactic
(** Generic monadic combinators for tactics. *)
module Monad : Monad.S withtype +'a t = 'a tactic
(** {7 Failure and backtracking} *)
(** [tclZERO e] fails with exception [e]. It has no success.
Exception is supposed to be non critical *) val tclZERO : ?info:Exninfo.info -> exn -> 'a tactic
(** [tclOR t1 t2] behaves like [t1] as long as [t1] succeeds. Whenever thesuccessesof[t1]havebeendepletedanditfailedwith[e], thenitbehavesas[t2e].Inotherwords,[tclOR]insertsa
backtracking point. In [t2], exception can be assumed non critical. *) val tclOR : 'a tactic -> (Exninfo.iexn -> 'a tactic) -> 'a tactic
(** [tclORELSE t1 t2] is equal to [t1] if [t1] has at least one successor[t2e]if[t1]failswith[e].Itisanalogousto [try/with]handlerofexceptioninthatitisnotabacktracking
point. In [t2], exception can be assumed non critical. *) val tclORELSE : 'a tactic -> (Exninfo.iexn -> 'a tactic) -> 'a tactic
(** [tclIFCATCH a s f] is a generalisation of {!tclORELSE}: if [a] succeedsatleastoncethenitbehavesas[tclBINDas]otherwise, if[a]failswith[e],thenitbehavesas[fe].In[f]
exception can be assumed non critical. *) val tclIFCATCH : 'a tactic -> ('a -> 'b tactic) -> (Exninfo.iexn -> 'b tactic) -> 'b tactic
(** [tclONCE t] behave like [t] except it has at most one success: [tclONCEt]stopsafterthefirstsuccessof[t].If[t]fails
with [e], [tclONCE t] also fails with [e]. *) val tclONCE : 'a tactic -> 'a tactic
(** [tclEXACTLY_ONCE e t] succeeds as [t] if [t] has exactly one success.Otherwiseitfails.Thetactic[t]isrununtilits firstsuccess,thenafailurewithexception[e]is simulated([e]hastobenoncritical).If[t] yieldsanothersuccess,then[tclEXACTLY_ONCEet]failswith [MoreThanOneSuccess](itisausererror).Otherwise, [tclEXACTLY_ONCEet]succeedswiththefirstsuccessof [t].Noticethatthechoiceof[e]isrelevant,asthepresenceof
further successes may depend on [e] (see {!tclOR}). *)
exception MoreThanOneSuccess val tclEXACTLY_ONCE : exn -> 'a tactic -> 'a tactic
(** [tclCASE t] splits [t] into its first success and a continuation.Itisthemostgeneralprimitivetocontrol
backtracking. *) type'a case =
| Fail of Exninfo.iexn
| Next of'a * (Exninfo.iexn -> 'a tactic) val tclCASE : 'a tactic -> 'a case tactic
(** [tclBREAK p t] is a generalization of [tclONCE t]. Instead of stoppingafterthefirstsuccess,itsucceedslike[t]untila failurewithanexception[e]suchthat[pe=Somee']israised.At whichpointitdropstheremainingsuccesses,failingwith[e'].
[tclONCE t] is equivalent to [tclBREAK (fun e -> Some e) t]. *) val tclBREAK : (Exninfo.iexn -> Exninfo.iexn option) -> 'a tactic -> 'a tactic
(** {7 Focusing tactics} *)
(** Represents a range selector as accepted by [tclFOCUSSELECTORLIST]. *) type goal_range_selector =
| NthSelector of int
| RangeSelector of (int * int)
| IdSelector of Names.Id.t
exception NoSuchGoals of int
exception CannotSelectShelvedAndFocused
(** [tclFOCUS i j t] applies [t] after focusing on the goals number [i]to[j](see{!focus}).Therestofthegoalsisrestoredafter thetacticaction.Ifthespecifiedrangedoesn'tcorrespondto existinggoals,failswiththe[nosuchgoal]argument,bydefault raising[NoSuchGoals](ausererror).Thisexceptioniscaughtat
toplevel with a default message. *) val tclFOCUS : ?nosuchgoal:'a tactic -> int -> int -> 'a tactic -> 'a tactic
(** [tclFOCUSLIST li t] applies [t] on the list of focused goals describedby[li].Eachelementof[li]isapair[(i,j)]denoting thegoalsnumberedfrom[i]to[j](inclusive,startingfrom1). Itwilltrytoapply[t]toallthevalidgoalsinanyofthese intervals.Ifthesetofsuchgoalsisnotasinglerange,thenit willmovegoalssuchthatitisasinglerange.(So,for instance,[[1,3-5];idtac.]isnottheidentity.) Ifthesetofsuchgoalsisempty,itwillfailwith[nosuchgoal],
by default raising [NoSuchGoals 0]. *) val tclFOCUSLIST : ?nosuchgoal:'a tactic -> (int * int) list -> 'a tactic -> 'a tactic
(** [tclFOCUSSELECTORLIST l t] applies [t] on the list of goal selectors describedby[l].Eachelementof[l]iseitherarangeselector [RangeSelector(i,j)]denotingthefocusedgoalsnumberedfrom[i]to[j] (inclusive,startingfrom1),oranamedselector[IdSelectorid]targetting agoalwhichmayormaynotbeshelved.
If all selected goals are shelved, then [tclFOCUSSHELF] is called. *) val tclFOCUSSELECTORLIST : ?nosuchgoal:'a tactic -> goal_range_selector list -> 'a tactic -> 'a tactic
(** [tclFOCUSID x t] applies [t] on a (single) focused goal like {!tclFOCUS}.Thegoalisfoundbyitsnameratherthanits
number. Fails with [nosuchgoal], by default raising [NoSuchGoals 1]. *) val tclFOCUSID : ?nosuchgoal:'a tactic -> Names.Id.t -> 'a tactic -> 'a tactic
(** [tclTRYFOCUS i j t] behaves like {!tclFOCUS}, except that if the specifiedrangedoesn'tcorrespondtoexistinggoals,behaveslike
[tclUNIT ()] instead of failing. *) val tclTRYFOCUS : int -> int -> unit tactic -> unit tactic
(** {7 Dispatching on goals} *)
(** Dispatch tacticals are used to apply a different tactic to each goalunderfocus.Theycomeintwoflavours:[tclDISPATCH]takesa listof[unittactic]-sandbuilda[unittactic].[tclDISPATCHL] takesalistof['atactic]andreturnsan['alisttactic].
Whenthelengthofthetacticlistisnotthenumberofgoal, raises[SizeMismatch(g,t)]where[g]isthenumberofavailable
goals, and [t] the number of tactics passed. *)
exception SizeMismatch of int*int val tclDISPATCH : unit tactic list -> unit tactic val tclDISPATCHL : 'a tactic list -> 'a list tactic
(** [tclEXTEND b r e] is a variant of {!tclDISPATCH}, where the [r] tacticis"repeated"enoughtimesuchthateverygoalhasatactic assignedtoit([b]isthelistoftacticsappliedtothefirst goals,[e]tothelastgoals,and[r]isappliedtoeverygoalin
between). *) val tclEXTEND : unit tactic list -> unit tactic -> unit tactic list -> unit tactic
(** [tclINDEPENDENT tac] runs [tac] on each goal successively, from thefirstonetothelastone.Backtrackinginonegoalis independentofbacktrackinginanother.Itisequivalentto
[tclEXTEND [] tac []]. *) val tclINDEPENDENT : unit tactic -> unit tactic val tclINDEPENDENTL: 'a tactic -> 'a list tactic
(** {7 Goal manipulation} *)
(** Shelves all the goals under focus. The goals are placed on the
shelf for later use (or being solved by side-effects). *) val shelve : unit tactic
(** Shelves the given list of goals, which might include some that are underfocusandsomethataren't.Allthegoalsareplacedonthe
shelf for later use (or being solved by side-effects). *) val shelve_goals : Evar.t list -> unit tactic
(** [unifiable sigma g l] checks whether [g] appears in another subgoalof[l].Thelist[l]maycontain[g],butitdoesnot
affect the result. Used by [shelve_unifiable]. *) val unifiable : Evd.evar_map -> Evar.t -> Evar.t list -> bool
(** Shelves the unifiable goals under focus, i.e. the goals which appearinothergoalsunderfocus(theunfocusedgoalsarenot
considered). *) val shelve_unifiable : unit tactic
(** [guard_no_unifiable] returns the list of unifiable goals if some
goals are unifiable (see {!shelve_unifiable}) in the current focus. *) val guard_no_unifiable : Names.Name.t listoption tactic
(** [unshelve l p] moves all the goals in [l] from the shelf and put them at
the end of the focused goals of p, if they are still undefined after [advance] *) val unshelve : Evar.t list -> proofview -> proofview
val filter_shelf : (Evar.t -> bool) -> proofview -> proofview
(** [depends_on g1 g2 sigma] checks if g1 occurs in the type/ctx of g2 *) val depends_on : Evd.evar_map -> Evar.t -> Evar.t -> bool
(** [with_shelf tac] executes [tac] and returns its result together with thesetofgoalsshelvedby[tac].Thecurrentshelfisunchanged
and the returned list contains only unsolved goals. *) val with_shelf : 'a tactic -> (Evar.t list * 'a) tactic
(** If [n] is positive, [cycle n] puts the [n] first goal last. If [n]
is negative, then it puts the [n] last goals first.*) val cycle : int -> unit tactic
(** [swap i j] swaps the position of goals number [i] and [j] (negativenumberscanbeusedtoaddressgoalsfromtheend.Goals areindexedfrom[1].Forsimplicityindex[0]correspondstogoal
[1] as well, rather than raising an error. *) val swap : int -> int -> unit tactic
(** [revgoals] reverses the list of focused goals. *) val revgoals : unit tactic
(** [numgoals] returns the number of goals under focus. *) val numgoals : int tactic
(** {7 Access primitives} *)
(** [tclEVARMAP] doesn't affect the proof, it returns the current
[evar_map]. *) val tclEVARMAP : Evd.evar_map tactic
(** [tclENV] doesn't affect the proof, it returns the current environment.Itisnottheenvironmentofaparticulargoal, ratherthe"global"environmentoftheproof.Thegoal-wise
environment is obtained via {!Proofview.Goal.env}. *) val tclENV : Environ.env tactic
(** {7 Put-like primitives} *)
(** [tclEFFECTS eff] add the effects [eff] to the current state. *) val tclEFFECTS : Evd.side_effects -> unit tactic
(** [mark_as_unsafe] declares the current tactic is unsafe. *) val mark_as_unsafe : unit tactic
(** Gives up on the goal under focus. Reports an unsafe status. Proofs
with given up goals cannot be closed. *) val give_up : unit tactic
(** {7 Control primitives} *)
(** [tclPROGRESS t] checks the state of the proof after [t]. It it is identicaltothestatebefore,then[tclPROGRESSt]fails,otherwise
it succeeds like [t]. *) val tclPROGRESS : 'a tactic -> 'a tactic
module Progress : sig (** [goal_equal ~evd ~extended_evd evar extended_evar] tests whether the[evar_info]from[evd]correspondingto[evar]isequaltothat from[extended_evd]correspondingto[extended_evar],upto existentialvariableinstantiationandequalisableuniverses.The universeconstraintsin[extended_evd]areassumedtobean
extension of the universe constraints in [evd]. *) val goal_equal :
evd:Evd.evar_map ->
extended_evd:Evd.evar_map ->
Evar.t ->
Evar.t -> bool end
(** Checks for interrupts *) val tclCHECKINTERRUPT : unit tactic
(** [tclTIMEOUT n t] can have only one success.
In case of timeout it fails with [tclZERO Tac_Timeout]. *) val tclTIMEOUTF : float -> 'a tactic -> 'a tactic val tclTIMEOUT : int -> 'a tactic -> 'a tactic
(** [tclTIME s t] displays time for each atomic call to t, using s as an
identifying annotation if present *) val tclTIME : stringoption -> 'a tactic -> 'a tactic
(** The primitives in the [Unsafe] module should be avoided as much as possible,sincetheycanmaketheproofstateinconsistent.Theyare neverthelesshelpful,inparticularwheninterfacingthepretypingand
the proof engine. *)
module Unsafe : sig
(** [tclEVARS sigma] replaces the current [evar_map] by [sigma]. If [sigma]hasnewunresolved[evar]-stheywillnotappearas goal.Ifgoalshavebeensolvedin[sigma]theywillstill
appear as unsolved goals. *) val tclEVARS : Evd.evar_map -> unit tactic
(** 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 ~before gls] adds the goals [gls] to the ones currently beingproved.If[before]istrue,itprependsthemtothelistoffocused goals,otherwiseitappendsthem(default).Ifagoalisalready
solved, it is not added. *) val tclNEWGOALS : ?before:bool -> Proofview_monad.goal_with_state list -> unit tactic
(** [tclNEWSHELVED gls] adds the goals [gls] to the shelf. If a
goal is already solved, it is not added. *) val tclNEWSHELVED : Evar.t list -> unit tactic
(** [tclSETGOALS gls] sets goals [gls] as the goals being under focus. If a
goal is already solved, it is not set. *) val tclSETGOALS : Proofview_monad.goal_with_state list -> unit tactic
(** [tclGETGOALS] returns the list of goals under focus. *) val tclGETGOALS : Proofview_monad.goal_with_state list tactic
(** [tclGETSHELF] returns the list of goals on the shelf. *) val tclGETSHELF : Evar.t list tactic
(** Sets the evar universe context. *) val tclEVARUNIVCONTEXT : UState.t -> unit tactic
(** Clears the future goals store in the proof view. *) val push_future_goals : proofview -> proofview
(** Give the evars the status of a goal (changes their source location
and makes them unresolvable for type classes. *) val mark_as_goals : Evd.evar_map -> Evar.t list -> Evd.evar_map
(** Make some evars unresolvable for type classes. Weneedtwofunctionsassomefunctionsusetheproofviewandothers directlymanipulatetheundelyingevar_map.
*) val mark_unresolvables : Evd.evar_map -> Evar.t list -> Evd.evar_map
val mark_as_unresolvables : proofview -> Evar.t list -> proofview
(** [advance sigma g] returns [Some g'] if [g'] is undefined and is thecurrentavatarof[g](forinstance[g]waschangedby[clear] into[g']).Itreturns[None]if[g]hasbeen(partially)
solved. *) val advance : Evd.evar_map -> Evar.t -> Evar.t option
(** [undefined sigma l] applies [advance] to the goals of [l], then returnsthesubsetofresultinggoalswhichhavenotyetbeen
defined *) val undefined : Evd.evar_map -> Proofview_monad.goal_with_state list ->
Proofview_monad.goal_with_state list
(** [update_sigma_univs] lifts [UState.update_sigma_univs] to the proofview *) val update_sigma_univs : UGraph.t -> proofview -> proofview
end
(** This module gives access to the innards of the monad. Its use is
restricted to very specific cases. *)
module UnsafeRepr : sig type state = Proofview_monad.Logical.Unsafe.state val repr : 'a tactic -> ('a, state, state, Exninfo.iexn) Logic_monad.BackState.t val make : ('a, state, state, Exninfo.iexn) Logic_monad.BackState.t -> 'a tactic end
(** {6 Goal-dependent tactics} *)
module Goal : sig
(** Type of goals. *) type t
(** [concl], [hyps], [env] and [sigma] given a goal [gl] return respectivelytheconclusionof[gl],thehypothesesof[gl],the environmentof[gl](i.e.theglobalenvironmentandthe
hypotheses) and the current evar map. *) val concl : t -> constr val relevance : t -> ERelevance.t val hyps : t -> named_context val env : t -> Environ.env val sigma : t -> Evd.evar_map val state : t -> Proofview_monad.StateStore.t
(** [enter t] applies the goal-dependent tactic [t] in each goal independently,inthemannerof{!tclINDEPENDENT}exceptthat
the current goal is also given as an argument to [t]. *) val enter : (t -> unit tactic) -> unit tactic
(** Like {!enter}, but assumes exactly one goal under focus, raising
a fatal error otherwise. *) val enter_one : ?__LOC__:string -> (t -> 'a tactic) -> 'a tactic
(** Recover the list of current goals under focus, without evar-normalization.
FIXME: encapsulate the level in an existential type. *) val goals : t tactic list tactic
(** [unsolved g] is [true] if [g] is still unsolved in the current
proof state. *) val unsolved : t -> bool tactic
(** Compatibility: avoid if possible *) val goal : t -> Evar.t
end
(** {6 Trace} *)
module Trace : sig
(** [record_info_trace t] behaves like [t] except the [info] trace
is stored. *) val record_info_trace : 'a tactic -> 'a tactic
val log : Proofview_monad.lazy_msg -> unit tactic val name_tactic : Proofview_monad.lazy_msg -> 'a tactic -> 'a tactic
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.