Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
Iris
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Terraform modules
Monitor
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Gaëtan Gilbert
Iris
Commits
ff447963
Commit
ff447963
authored
1 year ago
by
Robbert Krebbers
Browse files
Options
Downloads
Patches
Plain Diff
Use `_` prefix for private/internal tactics.
parent
07637e76
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
iris/proofmode/base.v
+8
-8
8 additions, 8 deletions
iris/proofmode/base.v
iris/proofmode/ltac_tactics.v
+114
-114
114 additions, 114 deletions
iris/proofmode/ltac_tactics.v
with
122 additions
and
122 deletions
iris/proofmode/base.v
+
8
−
8
View file @
ff447963
...
...
@@ -14,10 +14,10 @@ that in Ltac2. For most proofmode tactics we only need to iterate over a list
and [ltac1_list_rev_iter] allow us to do that while encapsulating the Ltac2
code. These tactics can be used as:
Ltac iTactic
_
xs :=
Ltac
_
iTactic xs :=
ltac1_list_rev_iter ltac:(fun x => /* stuff */) xs.
Tactic Notation "iTactic" "(" ne_ident_list(xs) ")" :=
iTactic
_
xs.
_
iTactic xs.
It is important to note that given one n-ary [Tactic Notation] we cannot call
another n-ary [Tactic Notation]. For example, the following does NOT work:
...
...
@@ -27,12 +27,12 @@ another n-ary [Tactic Notation]. For example, the following does NOT work:
iTactic (xs).
Because of this reason, as already shown above, we typically provide an [Ltac]
called [iTactic
_
] (note the underscore
), and define the [Tactic Notation] as a
wrapper, allowing us to write:
called [
_
iTactic] (note the underscore
to mark it is "private"), and define the
[Tactic Notation] as a
wrapper, allowing us to write:
Tactic Notation "iAnotherTactic" "(" ne_ident_list(xs) ")" :=
/* stuff */
iTactic
_
xs.
_
iTactic xs.
*)
Ltac2
of_ltac1_list
l
:=
Option
.
get
(
Ltac1
.
to_list
l
)
.
...
...
@@ -48,11 +48,11 @@ Ltac ltac1_list_rev_iter tac l :=
go
tac
l
.
(** Since the Ltac1-Ltac2 API only supports unit-returning functions, there is
no nice way to call [Ltac]s such as [iTactic
_
] above with the empty list. We
therefore often define a special version [iTactic0
_
] for the empty list. This
no nice way to call [Ltac]s such as [
_
iTactic] above with the empty list. We
therefore often define a special version [
_
iTactic0] for the empty list. This
version can be created using [with_ltac1_nil]:
Ltac iTactic0
_
:= with_ltac1_nil ltac:(fun xs => iTactic
_
xs)
Ltac
_
iTactic0 := with_ltac1_nil ltac:(fun xs =>
_
iTactic xs)
*)
Ltac
with_ltac1_nil
tac
:=
let
go
:=
ltac2
:(
tac
|
-
ltac1
:(
tac
l
|
-
tac
l
)
tac
(
Ltac1
.
of_list
[]))
in
...
...
This diff is collapsed.
Click to expand it.
iris/proofmode/ltac_tactics.v
+
114
−
114
View file @
ff447963
...
...
@@ -422,26 +422,26 @@ Ltac iFrameAnySpatial :=
let
Hs
:=
eval
cbv
in
(
env_dom
(
env_spatial
Δ
))
in
go
Hs
end
.
Local
Ltac
iFrame_go
Hs
:=
Local
Ltac
_
iFrame_go
Hs
:=
lazymatch
Hs
with
|
[]
=>
idtac
|
SelPure
::
?Hs
=>
iFrameAnyPure
;
iFrame_go
Hs
|
SelIntuitionistic
::
?Hs
=>
iFrameAnyIntuitionistic
;
iFrame_go
Hs
|
SelSpatial
::
?Hs
=>
iFrameAnySpatial
;
iFrame_go
Hs
|
SelIdent
?H
::
?Hs
=>
iFrameHyp
H
;
iFrame_go
Hs
|
SelPure
::
?Hs
=>
iFrameAnyPure
;
_
iFrame_go
Hs
|
SelIntuitionistic
::
?Hs
=>
iFrameAnyIntuitionistic
;
_
iFrame_go
Hs
|
SelSpatial
::
?Hs
=>
iFrameAnySpatial
;
_
iFrame_go
Hs
|
SelIdent
?H
::
?Hs
=>
iFrameHyp
H
;
_
iFrame_go
Hs
end
.
Ltac
iFrame0
_
Hs
:=
Ltac
_
iFrame0
Hs
:=
let
Hs
:=
sel_pat
.
parse
Hs
in
iFrame_go
Hs
.
Ltac
iFrame
_
ts
Hs
:=
_
iFrame_go
Hs
.
Ltac
_
iFrame
ts
Hs
:=
ltac1_list_iter
iFramePure
ts
;
iFrame0
_
Hs
.
_
iFrame0
Hs
.
Tactic
Notation
"iFrame"
:=
iFrameAnySpatial
.
Tactic
Notation
"iFrame"
"("
ne_constr_list
(
ts
)
")"
:=
iFrame
_
ts
""
.
Tactic
Notation
"iFrame"
constr
(
Hs
)
:=
iFrame0
_
Hs
.
Tactic
Notation
"iFrame"
"("
ne_constr_list
(
ts
)
")"
constr
(
Hs
)
:=
iFrame
_
ts
Hs
.
Tactic
Notation
"iFrame"
"("
ne_constr_list
(
ts
)
")"
:=
_
iFrame
ts
""
.
Tactic
Notation
"iFrame"
constr
(
Hs
)
:=
_
iFrame0
Hs
.
Tactic
Notation
"iFrame"
"("
ne_constr_list
(
ts
)
")"
constr
(
Hs
)
:=
_
iFrame
ts
Hs
.
Tactic
Notation
"iFrame"
"select"
open_constr
(
pat
)
:=
iSelect
pat
ltac
:(
fun
H
=>
iFrameHyp
H
)
.
...
...
@@ -635,26 +635,26 @@ Tactic Notation "iRevertHyp" constr(H) "with" tactic1(tac) :=
Tactic
Notation
"iRevertHyp"
constr
(
H
)
:=
iRevertHyp
H
with
(
fun
_
=>
idtac
)
.
Ltac
iRevert_go
Hs
:=
Ltac
_
iRevert_go
Hs
:=
lazymatch
Hs
with
|
[]
=>
idtac
|
ESelPure
::
?Hs
=>
repeat
match
goal
with
x
:
_
|
-
_
=>
revert
x
end
;
iRevert_go
Hs
|
ESelIdent
_
?H
::
?Hs
=>
iRevertHyp
H
;
iRevert_go
Hs
_
iRevert_go
Hs
|
ESelIdent
_
?H
::
?Hs
=>
iRevertHyp
H
;
_
iRevert_go
Hs
end
.
Ltac
iRevert0
_
Hs
:=
Ltac
_
iRevert0
Hs
:=
iStartProof
;
let
Hs
:=
iElaborateSelPat
Hs
in
iRevert_go
Hs
.
Ltac
iRevert
_
xs
Hs
:=
iRevert0
_
Hs
;
_
iRevert_go
Hs
.
Ltac
_
iRevert
xs
Hs
:=
_
iRevert0
Hs
;
ltac1_list_rev_iter
iForallRevert
xs
.
Tactic
Notation
"iRevert"
constr
(
Hs
)
:=
iRevert0
_
Hs
.
Tactic
Notation
"iRevert"
"("
ne_ident_list
(
xs
)
")"
:=
iRevert
_
xs
""
.
Tactic
Notation
"iRevert"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
:=
iRevert
_
xs
Hs
.
Tactic
Notation
"iRevert"
constr
(
Hs
)
:=
_
iRevert0
Hs
.
Tactic
Notation
"iRevert"
"("
ne_ident_list
(
xs
)
")"
:=
_
iRevert
xs
""
.
Tactic
Notation
"iRevert"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
:=
_
iRevert
xs
Hs
.
Tactic
Notation
"iRevert"
"select"
open_constr
(
pat
)
:=
iSelect
pat
ltac
:(
fun
H
=>
iRevertHyp
H
)
.
...
...
@@ -1257,7 +1257,7 @@ Local Tactic Notation "iAndDestructChoice" constr(H) "as" constr(d) constr(H') :
(** * Existential *)
Ltac
iExists
_
x
:=
Ltac
_
iExists
x
:=
iStartProof
;
eapply
tac_exist
;
[
tc_solve
||
...
...
@@ -1267,7 +1267,7 @@ Ltac iExists_ x :=
(* subgoal *)
]
.
Tactic
Notation
"iExists"
ne_uconstr_list_sep
(
xs
,
","
)
:=
ltac1_list_iter
iExists
_
xs
.
ltac1_list_iter
_
iExists
xs
.
Local
Tactic
Notation
"iExistDestruct"
constr
(
H
)
"as"
simple_intropattern
(
x
)
constr
(
Hx
)
:=
...
...
@@ -1458,17 +1458,17 @@ Local Ltac iDestructHypFindPat Hgo pat found pats :=
end
end
.
Ltac
iDestructHyp0
_
H
pat
:=
Ltac
_
iDestructHyp0
H
pat
:=
let
pats
:=
intro_pat
.
parse
pat
in
iDestructHypFindPat
H
pat
false
pats
.
Ltac
iDestructHyp
_
H
xs
pat
:=
Ltac
_
iDestructHyp
H
xs
pat
:=
ltac1_list_iter
ltac
:(
fun
x
=>
iExistDestruct
H
as
x
H
)
xs
;
iDestructHyp0
_
H
pat
.
_
iDestructHyp0
H
pat
.
Tactic
Notation
"iDestructHyp"
constr
(
H
)
"as"
constr
(
pat
)
:=
iDestructHyp0
_
H
pat
.
_
iDestructHyp0
H
pat
.
Tactic
Notation
"iDestructHyp"
constr
(
H
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iDestructHyp
_
H
xs
pat
.
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
_
iDestructHyp
H
xs
pat
.
(** * Combinining hypotheses *)
Tactic
Notation
"iCombine"
constr
(
Hs
)
"as"
constr
(
pat
)
:=
...
...
@@ -1560,7 +1560,7 @@ Tactic Notation "iCombine" constr(H1) constr(H2) "as" constr(pat1)
iCombine
[
H1
;
H2
]
as
pat1
gives
%
pat2
.
(** * Introduction tactic *)
Ltac
iIntros_go
pats
startproof
:=
Ltac
_
iIntros_go
pats
startproof
:=
lazymatch
pats
with
|
[]
=>
lazymatch
startproof
with
...
...
@@ -1572,70 +1572,70 @@ Ltac iIntros_go pats startproof :=
let
i
:=
fresh
in
iIntro
(
i
);
rename_by_string
i
s
;
iIntros_go
pats
startproof
|
IPure
IGallinaAnon
::
?pats
=>
iIntro
(?);
iIntros_go
pats
startproof
|
IIntuitionistic
(
IIdent
?H
)
::
?pats
=>
iIntro
#
H
;
iIntros_go
pats
false
|
IDrop
::
?pats
=>
iIntro
_;
iIntros_go
pats
startproof
|
IIdent
?H
::
?pats
=>
iIntro
H
;
iIntros_go
pats
startproof
_
iIntros_go
pats
startproof
|
IPure
IGallinaAnon
::
?pats
=>
iIntro
(?);
_
iIntros_go
pats
startproof
|
IIntuitionistic
(
IIdent
?H
)
::
?pats
=>
iIntro
#
H
;
_
iIntros_go
pats
false
|
IDrop
::
?pats
=>
iIntro
_;
_
iIntros_go
pats
startproof
|
IIdent
?H
::
?pats
=>
iIntro
H
;
_
iIntros_go
pats
startproof
(* Introduction patterns that can only occur at the top-level *)
|
IPureIntro
::
?pats
=>
iPureIntro
;
iIntros_go
pats
false
|
IModalIntro
::
?pats
=>
iModIntro
;
iIntros_go
pats
false
|
IForall
::
?pats
=>
repeat
iIntroForall
;
iIntros_go
pats
startproof
|
IAll
::
?pats
=>
repeat
(
iIntroForall
||
iIntro
);
iIntros_go
pats
startproof
|
IPureIntro
::
?pats
=>
iPureIntro
;
_
iIntros_go
pats
false
|
IModalIntro
::
?pats
=>
iModIntro
;
_
iIntros_go
pats
false
|
IForall
::
?pats
=>
repeat
iIntroForall
;
_
iIntros_go
pats
startproof
|
IAll
::
?pats
=>
repeat
(
iIntroForall
||
iIntro
);
_
iIntros_go
pats
startproof
(* Clearing and simplifying introduction patterns *)
|
ISimpl
::
?pats
=>
simpl
;
iIntros_go
pats
startproof
|
IClear
?H
::
?pats
=>
iClear
H
;
iIntros_go
pats
false
|
IClearFrame
?H
::
?pats
=>
iFrame
H
;
iIntros_go
pats
false
|
IDone
::
?pats
=>
try
done
;
iIntros_go
pats
startproof
|
ISimpl
::
?pats
=>
simpl
;
_
iIntros_go
pats
startproof
|
IClear
?H
::
?pats
=>
iClear
H
;
_
iIntros_go
pats
false
|
IClearFrame
?H
::
?pats
=>
iFrame
H
;
_
iIntros_go
pats
false
|
IDone
::
?pats
=>
try
done
;
_
iIntros_go
pats
startproof
(* Introduction + destruct *)
|
IIntuitionistic
?pat
::
?pats
=>
let
H
:=
iFresh
in
iIntro
#
H
;
iDestructHyp
H
as
pat
;
iIntros_go
pats
false
let
H
:=
iFresh
in
iIntro
#
H
;
iDestructHyp
H
as
pat
;
_
iIntros_go
pats
false
|
?pat
::
?pats
=>
let
H
:=
iFresh
in
iIntro
H
;
iDestructHyp
H
as
pat
;
iIntros_go
pats
false
let
H
:=
iFresh
in
iIntro
H
;
iDestructHyp
H
as
pat
;
_
iIntros_go
pats
false
end
.
Ltac
iIntros0
_
pat
:=
Ltac
_
iIntros0
pat
:=
let
pats
:=
intro_pat
.
parse
pat
in
iIntros_go
pats
true
.
Ltac
iIntros
_
xs
pat
:=
_
iIntros_go
pats
true
.
Ltac
_
iIntros
xs
pat
:=
ltac1_list_iter
ltac
:(
fun
x
=>
iIntro
(
x
))
xs
;
iIntros0
_
pat
.
_
iIntros0
pat
.
Tactic
Notation
"iIntros"
:=
iIntros0
_
[
IAll
]
.
Tactic
Notation
"iIntros"
constr
(
pat
)
:=
iIntros0
_
pat
.
Tactic
Notation
"iIntros"
:=
_
iIntros0
[
IAll
]
.
Tactic
Notation
"iIntros"
constr
(
pat
)
:=
_
iIntros0
pat
.
Tactic
Notation
"iIntros"
"("
ne_simple_intropattern_list
(
xs
)
")"
:=
iIntros
_
xs
""
.
_
iIntros
xs
""
.
Tactic
Notation
"iIntros"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iIntros
_
xs
pat
.
_
iIntros
xs
pat
.
Tactic
Notation
"iIntros"
constr
(
pat
)
"("
ne_simple_intropattern_list
(
xs
)
")"
:=
iIntros0
_
pat
;
iIntros
_
xs
""
.
_
iIntros0
pat
;
_
iIntros
xs
""
.
Tactic
Notation
"iIntros"
constr
(
pat1
)
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat2
)
:=
iIntros0
_
pat1
;
iIntros
_
xs
pat2
.
_
iIntros0
pat1
;
_
iIntros
xs
pat2
.
(* Used for generalization in [iInduction] and [iLöb] *)
Ltac
iRevertIntros_go
Hs
tac
:=
Ltac
_
iRevertIntros_go
Hs
tac
:=
lazymatch
Hs
with
|
[]
=>
tac
()
|
ESelPure
::
?Hs
=>
fail
"iRevertIntros: % not supported"
|
ESelIdent
?p
?H
::
?Hs
=>
iRevertHyp
H
;
iRevertIntros_go
Hs
tac
;
iIntro
H
as
p
|
ESelIdent
?p
?H
::
?Hs
=>
iRevertHyp
H
;
_
iRevertIntros_go
Hs
tac
;
iIntro
H
as
p
end
.
Ltac
iRevertIntros0
_
Hs
tac
:=
Ltac
_
iRevertIntros0
Hs
tac
:=
try
iStartProof
;
let
Hs
:=
iElaborateSelPat
Hs
in
iRevertIntros_go
Hs
tac
.
Ltac
iRevertIntros
_
xs
Hs
tac
:=
iRevertIntros0
_
Hs
ltac
:(
fun
_
=>
iRevert
_
xs
""
;
tac
();
iIntros
_
xs
""
)
.
_
iRevertIntros_go
Hs
tac
.
Ltac
_
iRevertIntros
xs
Hs
tac
:=
_
iRevertIntros0
Hs
ltac
:(
fun
_
=>
_
iRevert
xs
""
;
tac
();
_
iIntros
xs
""
)
.
Tactic
Notation
"iRevertIntros"
constr
(
Hs
)
"with"
tactic3
(
tac
)
:=
iRevertIntros0
_
Hs
tac
.
_
iRevertIntros0
Hs
tac
.
Tactic
Notation
"iRevertIntros"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
"with"
tactic3
(
tac
):=
iRevertIntros
_
xs
Hs
tac
.
_
iRevertIntros
xs
Hs
tac
.
Tactic
Notation
"iRevertIntros"
"with"
tactic3
(
tac
)
:=
iRevertIntros0
_
""
tac
.
_
iRevertIntros0
""
tac
.
Tactic
Notation
"iRevertIntros"
"("
ne_ident_list
(
xs
)
")"
"with"
tactic3
(
tac
):=
iRevertIntros
_
xs
""
tac
.
_
iRevertIntros
xs
""
tac
.
(** * Destruct and PoseProof tactics *)
(** The tactics [iDestruct] and [iPoseProof] are similar, but there are some
...
...
@@ -1681,25 +1681,25 @@ Tactic Notation "iDestructCore" open_constr(lem) "as" constr(p) tactic3(tac) :=
|
_
=>
iPoseProofCore
lem
as
p
tac
end
.
Ltac
iDestruct0
_
lem
pat
:=
Ltac
_
iDestruct0
lem
pat
:=
iDestructCore
lem
as
pat
(
fun
H
=>
iDestructHyp
H
as
pat
)
.
Ltac
iDestruct
_
lem
xs
pat
:=
iDestructCore
lem
as
pat
(
fun
H
=>
iDestructHyp
_
H
xs
pat
)
.
Ltac
_
iDestruct
lem
xs
pat
:=
iDestructCore
lem
as
pat
(
fun
H
=>
_
iDestructHyp
H
xs
pat
)
.
Tactic
Notation
"iDestruct"
open_constr
(
lem
)
"as"
constr
(
pat
)
:=
iDestruct0
_
lem
pat
.
_
iDestruct0
lem
pat
.
Tactic
Notation
"iDestruct"
open_constr
(
lem
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iDestruct
_
lem
xs
pat
.
_
iDestruct
lem
xs
pat
.
Tactic
Notation
"iDestruct"
open_constr
(
lem
)
"as"
"%"
simple_intropattern
(
pat
)
:=
iDestructCore
lem
as
true
(
fun
H
=>
iPure
H
as
pat
)
.
Tactic
Notation
"iDestruct"
"select"
open_constr
(
pat
)
"as"
constr
(
ipat
)
:=
iSelect
pat
ltac
:(
fun
H
=>
iDestruct0
_
H
ipat
)
.
iSelect
pat
ltac
:(
fun
H
=>
_
iDestruct0
H
ipat
)
.
Tactic
Notation
"iDestruct"
"select"
open_constr
(
pat
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
ipat
)
:=
iSelect
pat
ltac
:(
fun
H
=>
iDestruct
_
H
xs
ipat
)
.
iSelect
pat
ltac
:(
fun
H
=>
_
iDestruct
H
xs
ipat
)
.
Tactic
Notation
"iDestruct"
"select"
open_constr
(
pat
)
"as"
"%"
simple_intropattern
(
ipat
)
:=
iSelect
pat
ltac
:(
fun
H
=>
iDestruct
H
as
%
ipat
)
.
...
...
@@ -1707,7 +1707,7 @@ Tactic Notation "iPoseProof" open_constr(lem) "as" constr(pat) :=
iPoseProofCore
lem
as
pat
(
fun
H
=>
iDestructHyp
H
as
pat
)
.
Tactic
Notation
"iPoseProof"
open_constr
(
lem
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iPoseProofCore
lem
as
pat
(
fun
H
=>
iDestructHyp
_
H
xs
pat
)
.
iPoseProofCore
lem
as
pat
(
fun
H
=>
_
iDestructHyp
H
xs
pat
)
.
(** * Induction *)
(* An invocation of [iInduction (x) as pat IH forall (x1...xn) Hs] will
...
...
@@ -1761,48 +1761,48 @@ Ltac iHypsContaining x :=
let
Γs
:=
lazymatch
goal
with
|
-
envs_entails
(
Envs
_
?Γs
_)
_
=>
Γs
end
in
let
Hs
:=
go
Γp
x
(
@
nil
ident
)
in
go
Γs
x
Hs
.
Ltac
iInduction
_
x
xs
Hs
tac
IH
:=
Ltac
_
iInduction
x
xs
Hs
tac
IH
:=
(* FIXME: We should be able to do this in a more sane way, by concatenating
the spec patterns instead of calling [iRevertIntros] multiple times. *)
iRevertIntros0
_
Hs
ltac
:(
fun
_
=>
iRevertIntros
_
xs
"∗"
ltac
:(
fun
_
=>
_
iRevertIntros0
Hs
ltac
:(
fun
_
=>
_
iRevertIntros
xs
"∗"
ltac
:(
fun
_
=>
let
Hsx
:=
iHypsContaining
x
in
iRevertIntros0
_
Hsx
ltac
:(
fun
_
=>
_
iRevertIntros0
Hsx
ltac
:(
fun
_
=>
iInductionCore
tac
as
IH
)
)
)
.
Ltac
iInduction0
_
x
Hs
tac
IH
:=
with_ltac1_nil
ltac
:(
fun
xs
=>
iInduction
_
x
xs
Hs
tac
IH
)
.
Ltac
_
iInduction0
x
Hs
tac
IH
:=
with_ltac1_nil
ltac
:(
fun
xs
=>
_
iInduction
x
xs
Hs
tac
IH
)
.
(* Without induction scheme *)
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
:=
iInduction0
_
x
""
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
_
iInduction0
x
""
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"forall"
"("
ne_ident_list
(
xs
)
")"
:=
iInduction
_
x
xs
""
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
_
iInduction
x
xs
""
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"forall"
constr
(
Hs
)
:=
iInduction0
_
x
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
_
iInduction0
x
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"forall"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
:=
iInduction
_
x
xs
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
_
iInduction
x
xs
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
)
IH
.
(* With induction scheme *)
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"using"
uconstr
(
u
)
:=
iInduction0
_
x
""
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
_
iInduction0
x
""
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"using"
uconstr
(
u
)
"forall"
"("
ne_ident_list
(
xs
)
")"
:=
iInduction
_
x
xs
""
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
_
iInduction
x
xs
""
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"using"
uconstr
(
u
)
"forall"
constr
(
Hs
)
:=
iInduction0
_
x
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
_
iInduction0
x
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
Tactic
Notation
"iInduction"
constr
(
x
)
"as"
simple_intropattern
(
pat
)
constr
(
IH
)
"using"
uconstr
(
u
)
"forall"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
:=
iInduction
_
x
xs
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
_
iInduction
x
xs
Hs
ltac
:(
fun
_
=>
induction
x
as
pat
using
u
)
IH
.
(** * Löb Induction *)
Tactic
Notation
"iLöbCore"
"as"
constr
(
IH
)
:=
...
...
@@ -1821,25 +1821,25 @@ Tactic Notation "iLöbCore" "as" constr (IH) :=
|
_
=>
idtac
end
]
.
Ltac
iLöb
_
xs
Hs
IH
:=
Ltac
_
iLöb
xs
Hs
IH
:=
(* FIXME: We should be able to do this in a more sane way, by concatenating
the spec patterns instead of calling [iRevertIntros] multiple times. *)
iRevertIntros0
_
Hs
ltac
:(
fun
_
=>
iRevertIntros
_
xs
"∗"
ltac
:(
fun
_
=>
_
iRevertIntros0
Hs
ltac
:(
fun
_
=>
_
iRevertIntros
xs
"∗"
ltac
:(
fun
_
=>
iLöbCore
as
IH
)
)
.
Ltac
iLöb0
_
Hs
IH
:=
with_ltac1_nil
ltac
:(
fun
xs
=>
iLöb
_
xs
Hs
IH
)
.
Ltac
_
iLöb0
Hs
IH
:=
with_ltac1_nil
ltac
:(
fun
xs
=>
_
iLöb
xs
Hs
IH
)
.
Tactic
Notation
"iLöb"
"as"
constr
(
IH
)
:=
iLöb0
_
""
IH
.
_
iLöb0
""
IH
.
Tactic
Notation
"iLöb"
"as"
constr
(
IH
)
"forall"
"("
ne_ident_list
(
xs
)
")"
:=
iLöb
_
xs
""
IH
.
_
iLöb
xs
""
IH
.
Tactic
Notation
"iLöb"
"as"
constr
(
IH
)
"forall"
constr
(
Hs
)
:=
iLöb0
_
Hs
IH
.
_
iLöb0
Hs
IH
.
Tactic
Notation
"iLöb"
"as"
constr
(
IH
)
"forall"
"("
ne_ident_list
(
xs
)
")"
constr
(
Hs
)
:=
iLöb0
_
xs
Hs
IH
.
_
iLöb0
xs
Hs
IH
.
(** * Assert *)
(* The argument [p] denotes whether [Q] is persistent. It can either be a
...
...
@@ -1866,16 +1866,16 @@ Tactic Notation "iAssertCore" open_constr(Q) "as" constr(p) tactic3(tac) :=
end
.
Tactic
Notation
"iAssert"
open_constr
(
Q
)
"with"
constr
(
Hs
)
"as"
constr
(
pat
)
:=
iAssertCore
Q
with
Hs
as
pat
(
fun
H
=>
iDestructHyp0
_
H
pat
)
.
iAssertCore
Q
with
Hs
as
pat
(
fun
H
=>
_
iDestructHyp0
H
pat
)
.
Tactic
Notation
"iAssert"
open_constr
(
Q
)
"with"
constr
(
Hs
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iAssertCore
Q
with
Hs
as
pat
(
fun
H
=>
iDestructHyp
_
H
xs
pat
)
.
iAssertCore
Q
with
Hs
as
pat
(
fun
H
=>
_
iDestructHyp
H
xs
pat
)
.
Tactic
Notation
"iAssert"
open_constr
(
Q
)
"as"
constr
(
pat
)
:=
iAssertCore
Q
as
pat
(
fun
H
=>
iDestructHyp0
_
H
pat
)
.
iAssertCore
Q
as
pat
(
fun
H
=>
_
iDestructHyp0
H
pat
)
.
Tactic
Notation
"iAssert"
open_constr
(
Q
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iAssertCore
Q
as
pat
(
fun
H
=>
iDestructHyp
_
H
xs
pat
)
.
iAssertCore
Q
as
pat
(
fun
H
=>
_
iDestructHyp
H
xs
pat
)
.
Tactic
Notation
"iAssert"
open_constr
(
Q
)
"with"
constr
(
Hs
)
"as"
"%"
simple_intropattern
(
pat
)
:=
...
...
@@ -1938,7 +1938,7 @@ Tactic Notation "iMod" open_constr(lem) "as" constr(pat) :=
iDestructCore
lem
as
false
(
fun
H
=>
iModCore
H
as
H
;
last
iDestructHyp
H
as
pat
)
.
Tactic
Notation
"iMod"
open_constr
(
lem
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iDestructCore
lem
as
false
(
fun
H
=>
iModCore
H
as
H
;
last
iDestructHyp
_
H
xs
pat
)
.
iDestructCore
lem
as
false
(
fun
H
=>
iModCore
H
as
H
;
last
_
iDestructHyp
H
xs
pat
)
.
Tactic
Notation
"iMod"
open_constr
(
lem
)
"as"
"%"
simple_intropattern
(
pat
)
:=
iDestructCore
lem
as
false
(
fun
H
=>
iModCore
H
as
H
;
iPure
H
as
pat
)
.
...
...
@@ -2017,13 +2017,13 @@ Tactic Notation "iInvCore" constr(N) "as" constr(Hclose) "in" tactic3(tac) :=
Tactic
Notation
"iInvCore"
constr
(
N
)
"in"
tactic3
(
tac
)
:=
iInvCore
N
with
"[$]"
as
(
@
None
string
)
in
tac
.
Ltac
iDestructAccAndHyp0
pat
x
H
:=
Ltac
_
iDestructAccAndHyp0
pat
x
H
:=
lazymatch
type
of
x
with
|
unit
=>
destruct
x
as
[];
iDestructHyp0
_
H
pat
|
unit
=>
destruct
x
as
[];
_
iDestructHyp0
H
pat
|
_
=>
fail
"Missing intro pattern for accessor variable"
end
.
Ltac
iDestructAccAndHyp
xs
pat
x
H
:=
Ltac
_
iDestructAccAndHyp
xs
pat
x
H
:=
let
go
:=
ltac2
:(
tac
xs
|
-
match
of_ltac1_list
xs
with
|
[]
=>
...
...
@@ -2033,37 +2033,37 @@ Ltac iDestructAccAndHyp xs pat x H :=
ltac1
:(
tac
xs'
|
-
tac
xs'
)
tac
(
Ltac1
.
of_list
xs'
)
end
)
in
lazymatch
type
of
x
with
|
unit
=>
destruct
x
as
[];
iDestructHyp
_
H
xs
pat
|
_
=>
revert
x
;
go
ltac
:(
fun
xs'
=>
iDestructHyp
_
H
xs'
pat
)
xs
|
unit
=>
destruct
x
as
[];
_
iDestructHyp
H
xs
pat
|
_
=>
revert
x
;
go
ltac
:(
fun
xs'
=>
_
iDestructHyp
H
xs'
pat
)
xs
end
.
(* With everything *)
Tactic
Notation
"iInv"
constr
(
N
)
"with"
constr
(
Hs
)
"as"
constr
(
pat
)
constr
(
Hclose
)
:=
iInvCore
N
with
Hs
as
(
Some
Hclose
)
in
iDestructAccAndHyp0
pat
.
iInvCore
N
with
Hs
as
(
Some
Hclose
)
in
_
iDestructAccAndHyp0
pat
.
Tactic
Notation
"iInv"
constr
(
N
)
"with"
constr
(
Hs
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
constr
(
Hclose
)
:=
iInvCore
N
with
Hs
as
(
Some
Hclose
)
in
iDestructAccAndHyp
xs
pat
.
iInvCore
N
with
Hs
as
(
Some
Hclose
)
in
_
iDestructAccAndHyp
xs
pat
.
(* Without closing view shift *)
Tactic
Notation
"iInv"
constr
(
N
)
"with"
constr
(
Hs
)
"as"
constr
(
pat
)
:=
iInvCore
N
with
Hs
in
iDestructAccAndHyp0
pat
.
iInvCore
N
with
Hs
in
_
iDestructAccAndHyp0
pat
.
Tactic
Notation
"iInv"
constr
(
N
)
"with"
constr
(
Hs
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iInvCore
N
with
Hs
in
iDestructAccAndHyp
xs
pat
.
iInvCore
N
with
Hs
in
_
iDestructAccAndHyp
xs
pat
.
(* Without selection pattern *)
Tactic
Notation
"iInv"
constr
(
N
)
"as"
constr
(
pat
)
constr
(
Hclose
)
:=
iInvCore
N
as
(
Some
Hclose
)
in
iDestructAccAndHyp0
pat
.
iInvCore
N
as
(
Some
Hclose
)
in
_
iDestructAccAndHyp0
pat
.
Tactic
Notation
"iInv"
constr
(
N
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
constr
(
Hclose
)
:=
iInvCore
N
as
(
Some
Hclose
)
in
iDestructAccAndHyp
xs
pat
.
iInvCore
N
as
(
Some
Hclose
)
in
_
iDestructAccAndHyp
xs
pat
.
(* Without both *)
Tactic
Notation
"iInv"
constr
(
N
)
"as"
constr
(
pat
)
:=
iInvCore
N
in
iDestructAccAndHyp0
pat
.
iInvCore
N
in
_
iDestructAccAndHyp0
pat
.
Tactic
Notation
"iInv"
constr
(
N
)
"as"
"("
ne_simple_intropattern_list
(
xs
)
")"
constr
(
pat
)
:=
iInvCore
N
in
iDestructAccAndHyp
xs
pat
.
iInvCore
N
in
_
iDestructAccAndHyp
xs
pat
.
(** Miscellaneous *)
Tactic
Notation
"iAccu"
:=
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment