1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
.. extracted from Gallina extensions chapter
.. _existential-variables:
Existential variables
---------------------
:gdef:`Existential variables <existential variable>` represent as yet unknown
values.
.. insertprodn term_evar term_evar
.. prodn::
term_evar ::= _
| ?[ @ident ]
| ?[ ?@ident ]
| ?@ident {? @%{ {+; @ident := @term } %} }
Coq terms can include existential variables that represent unknown
subterms that are eventually replaced with actual subterms.
Existential variables are generated in place of unsolved implicit
arguments or “_” placeholders when using commands such as ``Check`` (see
Section :ref:`requests-to-the-environment`) or when using tactics such as
:tacn:`refine`, as well as in place of unsolved instances when using
tactics such that :tacn:`eapply`. An existential
variable is defined in a context, which is the context of variables of
the placeholder which generated the existential variable, and a type,
which is the expected type of the placeholder.
As a consequence of typing constraints, existential variables can be
duplicated in such a way that they possibly appear in different
contexts than their defining context. Thus, any occurrence of a given
existential variable comes with an instance of its original context.
In the simple case, when an existential variable denotes the
placeholder which generated it, or is used in the same context as the
one in which it was generated, the context is not displayed and the
existential variable is represented by “?” followed by an identifier.
.. coqtop:: all
Parameter identity : forall (X:Set), X -> X.
Check identity _ _.
Check identity _ (fun x => _).
In the general case, when an existential variable :n:`?@ident` appears
outside its context of definition, its instance, written in the
form :n:`{ {*; @ident := @term} }`, is appended to its name, indicating
how the variables of its defining context are instantiated.
Only the variables that are defined in another context are displayed:
this is why an existential variable used in the same context as its
context of definition is written with no instance.
This behavior may be changed: see :ref:`explicit-display-existentials`.
.. coqtop:: all
Check (fun x y => _) 0 1.
Existential variables can be named by the user upon creation using
the syntax :n:`?[@ident]`. This is useful when the existential
variable needs to be explicitly handled later in the script (e.g.
with a named-goal selector, see :ref:`goal-selectors`).
.. extracted from Gallina chapter
.. index:: _
Inferable subterms
~~~~~~~~~~~~~~~~~~
.. todo: This topic deserves considerably more explanation, but this will have
to do for now
@name allows `_` (used in 43 places in the grammar), but IIUC is semantically restricted.
Some of the cases:
* match expressions in terms (see :n:`@term_match`)
* binders (see :n:`@name`) in let, functions
* function parameters
* universe levels
relation to implicit arguments?
also intropatterns and hints paths, which are not terms
:n:`@term`\s may use :gdef:`holes <hole>`, denoted by :n:`_`, for purposes such as:
* Omitting redundant subterms. Redundant subterms that Coq is able to infer can
be replaced with :n:`_`. For example HELP ME HERE.
* Indicating where existential variables should be created in e* tactics such as
:tacn:`assert`.
is it possible to see holes in the context for any of these?
Expressions often contain redundant pieces of information. Subterms that can be
automatically inferred by Coq can be replaced by the symbol ``_`` and Coq will
guess the missing piece of information.
e* tactics that can create existential variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A number of tactics have companion tactics that create existential variables
when the base tactic would fail because of uninstantiated variables.
The companion tactic names begin with an :n:`e` followed by the name of the
base tactic.
For example, :tacn:`eapply` works the same way as :tacn:`apply`, except that
it will create new existential variable(s) when :tacn:`apply` would fail.
.. example:: apply vs eapply
Both tactics unify the goal with :n:`n < p` in the theorem. :n:`m` is
unspecified. This makes :tacn:`apply` fail, while :tacn:`eapply`
creates a new existential variable :n:`?m`.
.. coqtop:: none reset
Require Import Arith.
Goal forall i j, i < j.
intros.
.. coqtop:: all
(* Theorem lt_trans : forall n m p, n < m -> m < p -> n < p. *)
Fail apply Nat.lt_trans.
eapply Nat.lt_trans.
The :n:`e*` tactics include:
.. list-table::
* - :tacn:`eapply`
- :tacn:`eassert`
- :tacn:`eassumption`
- :tacn:`eauto`
* - :tacn:`ecase`
- :tacn:`econstructor`
- :tacn:`edestruct`
- :tacn:`ediscriminate`
* - :tacn:`eelim`
- :tacn:`eenough`
- :tacn:`eexact`
- :tacn:`eexists`
* - :tacn:`einduction`
- :tacn:`einjection`
- :tacn:`eintros`
- :tacn:`eleft`
* - :tacn:`epose`
- :tacn:`eremember`
- :tacn:`erewrite`
- :tacn:`eright`
* - :tacn:`eset`
- :tacn:`esimplify_eq`
- :tacn:`esplit`
- :tacn:`etransitivity`
Note that :tacn:`eassumption` and :tacn:`eauto` behave differently from the
others.
Automatic resolution of existential variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Existential variables that are used in other goals are generally resolved
automatically as a side effect of other tactics.
.. _automatic-evar-resolution:
.. example:: Automatic resolution of existential variables
:n:`?x` and :n:`?m` are used in other goals. The :tacn:`exact`
shown below determines the values of these variables by unification,
which resolves them.
.. coqtop:: reset in
Require Import Arith.
Set Printing Goal Names.
Goal forall n m, n <= m -> ~ m < n.
.. coqtop:: all
intros x y H1 H2.
eapply Nat.lt_irrefl. (* creates ?x : nat as a shelved goal *)
eapply Nat.le_lt_trans. (* creates ?m : nat as a shelved goal *)
Unshelve. (* moves the shelved goals into focus--not needed and usually not done *)
exact H1. (* resolves the first goal and by side effect ?x and ?m *)
The :n:`?x` and :n:`?m` goals ask for proof that :n:`nat` has an
:term:`inhabitant`, i.e. it is not an empty type. This can be proved directly
by applying a constructor of :n:`nat`, which assigns values for :n:`?x` and
:n:`?m`. However if you choose poorly, you can end up with unprovable goals
(in this case :n:`0 < 0`). Like this:
.. coqtop:: reset none
Require Import Arith.
Set Printing Goal Names.
Goal forall n m, n <= m -> ~ m < n.
intros x y H1 H2.
eapply Nat.lt_irrefl. (* creates ?x : nat as a shelved goal *)
eapply Nat.le_lt_trans. (* creates ?m : nat as a shelved goal *)
.. coqtop:: out
Unshelve. (* moves the shelved goals into focus--not needed and usually not done *)
.. coqtop:: all
3-4: apply 0. (* assigns values to ?x and ?m *)
.. extracted from Gallina extensions chapter
.. _explicit-display-existentials:
Explicit display of existential instances for pretty-printing
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.. flag:: Printing Existential Instances
Activates the full display of how the
context of an existential variable is instantiated at each of the
occurrences of the existential variable. Off by default.
.. coqtop:: all
Check (fun x y => _) 0 1.
Set Printing Existential Instances.
Check (fun x y => _) 0 1.
.. _tactics-in-terms:
Solving existential variables using tactics
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Instead of letting the unification engine try to solve an existential
variable by itself, one can also provide an explicit hole together
with a tactic to solve it. Using the syntax ``ltac:(``\ `tacexpr`\ ``)``, the user
can put a tactic anywhere a term is expected. The order of resolution
is not specified and is implementation-dependent. The inner tactic may
use any variable defined in its scope, including repeated alternations
between variables introduced by term binding as well as those
introduced by tactic binding. The expression `tacexpr` can be any tactic
expression as described in :ref:`ltac`.
.. coqtop:: all
Definition foo (x : nat) : nat := ltac:(exact x).
This construction is useful when one wants to define complicated terms
using highly automated tactics without resorting to writing the proof-term
by means of the interactive proof engine.
|