Skip to content

Commit b9c4f34

Browse files
committed
Merge remote-tracking branch 'upstream/master' into Imports
2 parents 5a36c7f + 3d3dfe0 commit b9c4f34

37 files changed

Lines changed: 1189 additions & 398 deletions

.github/workflows/build.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ jobs:
8282
path: Iris/.lake
8383
- name: Read pinned Rocq commit
8484
id: rocq-commit
85-
run: echo "sha=$(cat scripts/ROCQ_REVISION)" >> "$GITHUB_OUTPUT"
85+
run: |
86+
sha=$(cat scripts/ROCQ_REVISION)
87+
echo "sha=$sha" >> "$GITHUB_OUTPUT"
8688
- name: Cache Rocq definitions
8789
uses: actions/cache@v6
8890
with:

.github/workflows/check-stale.yml

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,9 @@ jobs:
2121
- name: Resolve Iris-Rocq master to a commit SHA
2222
id: rocq-commit
2323
run: |
24-
sha=$(curl -fsSL \
25-
"https://gitlab.mpi-sws.org/api/v4/projects/iris%2Firis/repository/commits/master" \
24+
set -euo pipefail
25+
url=$(python3 scripts/check_porting.py --print commit-api-url)
26+
sha=$(curl -fsSL "$url" \
2627
| python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])')
2728
echo "sha=$sha" >> "$GITHUB_OUTPUT"
2829

Iris/Iris/HeapLang/ProofMode.lean

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -658,11 +658,11 @@ elab "wp_store" : tactic =>
658658
let ⟨_, name, vid, _, hyps'', pfSplit⟩ ←
659659
lookupPointsTo `wp_store mvar hgs hyps' l q(DFrac.own 1) q(false)
660660

661-
let hyps''' := hyps''.add bi name vid q(false) q(pointsTo $l (DFrac.own 1) (some $v'))
661+
let ⟨_, hyps''', pf'''⟩ := hyps''.add bi name vid q(false) q(pointsTo $l (DFrac.own 1) (some $v'))
662662

663663
let pfCont ← finishHeapOp hyps''' hgs s E K q(hl_val(#())) Φ
664664

665-
mvar.assign q(tac_wp_store (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit $pfCont)
665+
mvar.assign q(tac_wp_store (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit <| $(pf''').mp.trans $pfCont)
666666

667667
elab "wp_xchg" : tactic =>
668668
runTacticHeapWp `wp_xchg fun mvar {bi, s, E, e, Φ, hgs, eΔ', hyps', pfLater, ..} => do
@@ -676,11 +676,11 @@ elab "wp_xchg" : tactic =>
676676
let ⟨v, name, vid, _, hyps'', pfSplit⟩ ←
677677
lookupPointsTo `wp_xchg mvar hgs hyps' l q(DFrac.own 1) q(false)
678678

679-
let hyps''' := hyps''.add bi name vid q(false) q(pointsTo $l (DFrac.own 1) (some $v'))
679+
let ⟨_, hyps''', pf'''⟩ := hyps''.add bi name vid q(false) q(pointsTo $l (DFrac.own 1) (some $v'))
680680

681681
let pfCont ← finishHeapOp hyps''' hgs s E K v Φ
682682

683-
mvar.assign q(tac_wp_xchg (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit $pfCont)
683+
mvar.assign q(tac_wp_xchg (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit <| $(pf''').mp.trans $pfCont)
684684

685685
elab "wp_faa" : tactic =>
686686
runTacticHeapWp `wp_faa fun mvar {bi, s, E, e, Φ, hgs, eΔ', hyps', pfLater, ..} => do
@@ -703,12 +703,12 @@ elab "wp_faa" : tactic =>
703703
have pfSplit : Q($eΔ' ⊣⊢ $eΔ'' ∗
704704
pointsTo $l (DFrac.own 1) (some (Val.lit (BaseLit.int $z1)))) := pfSplit
705705

706-
let hyps''' := hyps''.add bi name vid q(false)
706+
let ⟨_, hyps''', pf'''⟩ := hyps''.add bi name vid q(false)
707707
q(pointsTo $l (DFrac.own 1) (some (Val.lit (BaseLit.int ($z1 + $z2)))))
708708

709709
let pfCont ← finishHeapOp hyps''' hgs s E K q(Val.lit (BaseLit.int $z1)) Φ
710710

711-
mvar.assign q(tac_wp_faa (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit $pfCont)
711+
mvar.assign q(tac_wp_faa (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit <| $(pf''').mp.trans $pfCont)
712712

713713
elab "wp_cmpxchg_suc" : tactic =>
714714
runTacticHeapWp `wp_cmpxchg_suc fun mvar {bi, s, E, e, Φ, hgs, eΔ', hyps', pfLater, ..} => do
@@ -729,14 +729,14 @@ elab "wp_cmpxchg_suc" : tactic =>
729729
-- check equality, don't throw hard error to match Rocq behavior
730730
let pfEq ← iSolveSidecondition q($v = $v1) (failOnUnsolved := false)
731731

732-
let hyps''' := hyps''.add bi name vid q(false)
732+
let ⟨_, hyps''', pf'''⟩ := hyps''.add bi name vid q(false)
733733
q(pointsTo $l (DFrac.own 1) (some $v2))
734734

735735
let pfCont ← finishHeapOp hyps''' hgs s E K
736736
q(Val.pair $v (Val.lit (BaseLit.bool true))) Φ
737737

738738
mvar.assign
739-
q(tac_wp_cmpXchg_suc (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit $pfEq $pfSafe $pfCont)
739+
q(tac_wp_cmpXchg_suc (ι := $hgs) (Δ' := $eΔ') $pfLater $pfSplit $pfEq $pfSafe <| $(pf''').mp.trans $pfCont)
740740

741741
elab "wp_cmpxchg_fail" : tactic =>
742742
runTacticHeapWp `wp_cmpxchg_fail fun mvar {s, E, e, Φ, hgs, eΔ', hyps', pfLater, ..} => do
@@ -779,7 +779,7 @@ elab "wp_cmpxchg" " with" colGt ppSpace h1:binderIdent colGt ppSpace h2:binderId
779779
let ⟨v, name, vid, eΔ'', hyps'', pfSplit⟩ ←
780780
lookupPointsTo `wp_cmpxchg mvar hgs hyps' l q(DFrac.own 1) q(false)
781781

782-
let hypsSuc := hyps''.add bi name vid q(false)
782+
let ⟨_, hypsSuc, pfEq⟩ := hyps''.add bi name vid q(false)
783783
q(pointsTo $l (DFrac.own 1) (some $v2))
784784

785785
-- check safety, don't throw hard error to match Rocq behavior
@@ -793,7 +793,7 @@ elab "wp_cmpxchg" " with" colGt ppSpace h1:binderIdent colGt ppSpace h2:binderId
793793
Qq.withLocalDeclDQ sucName q($v = $v1) fun _h => do
794794
let pf ← finishHeapOp hypsSuc hgs s E K
795795
q(Val.pair $v (Val.lit (BaseLit.bool true))) Φ
796-
mkLambdaFVars #[_h] pf
796+
mkLambdaFVars #[_h] q($(pfEq).mp.trans $pf)
797797

798798
let (failName, _) ← getFreshName h2
799799
let pfFail : Q($v ≠ $v1 → $eΔ' ⊢
@@ -843,11 +843,11 @@ elab "wp_alloc" colGt ppSpace loc:binderIdent " with" colGt ppSpace hyp:binderId
843843
Wp.wp (self := wp.def (ι := @HeapLang $hlc $GF $hgs)) $s $E
844844
(ProgramLogic.fill $K (Exp.ofVal (Expr := Exp) (Val.lit (BaseLit.loc l)))) $Φ) ←
845845
Qq.withLocalDeclDQ locName q(Loc) fun l => do
846-
let ⟨_, hyps''⟩ ← hyps'.addWithInfo bi hyp q(false)
846+
let ⟨_, _, hyps'', pfEq⟩ ← hyps'.addWithInfo bi hyp q(false)
847847
q(pointsTo $l (DFrac.own 1) (some $v))
848848

849849
let pf ← finishHeapOp hyps'' hgs s E K q(Val.lit (BaseLit.loc $l)) Φ
850-
mkLambdaFVars #[l] pf
850+
mkLambdaFVars #[l] q($(pfEq).mp.trans $pf)
851851

852852
mvar.assign q(tac_wp_alloc (ι := $hgs) (Δ' := $eΔ') $pfLater $pfCont)
853853

Iris/Iris/HeapLang/Syntax.lean

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,21 @@ module
77

88
public import Iris.Std.Infinite
99
public import Iris.ProgramLogic.Language
10+
meta import Iris.Std.RocqPorting
1011

1112
@[expose] public section
1213
namespace Iris.HeapLang
1314

14-
@[ext]
15+
@[ext, rocq_alias heap_lang.loc]
1516
structure Loc where
1617
mk ::
1718
n : Int
1819
deriving Inhabited, Repr, DecidableEq
1920

21+
attribute [rocq_alias heap_lang.Loc.inhabited] instInhabitedLoc
22+
attribute [rocq_alias heap_lang.Loc.eq_dec] instDecidableEqLoc
23+
24+
@[rocq_alias heap_lang.Loc.infinite]
2025
instance : InfiniteType Loc where
2126
enum n := .mk n
2227
enum_inj n m := by grind
@@ -47,7 +52,7 @@ instance : Zero Loc where
4752
theorem loc_add_n (l : Loc) n :
4853
(l + n).n = l.n + n := by simp [HAdd.hAdd]
4954

50-
@[ext]
55+
@[ext, rocq_alias heap_lang.heap_lang.proph_id]
5156
structure ProphId where
5257
mk ::
5358
n : Nat
@@ -78,6 +83,7 @@ inductive Binder where
7883
| named (name : String)
7984
deriving Inhabited, Repr, DecidableEq
8085

86+
@[rocq_alias heap_lang.heap_lang.base_lit]
8187
inductive BaseLit where
8288
| int (n : Int)
8389
| bool (b : Bool)
@@ -87,11 +93,13 @@ inductive BaseLit where
8793
| prophecy (p : ProphId)
8894
deriving Inhabited, Repr, DecidableEq
8995

96+
@[rocq_alias heap_lang.heap_lang.un_op]
9097
inductive UnOp where
9198
| neg
9299
| minus
93100
deriving Inhabited, Repr, DecidableEq
94101

102+
@[rocq_alias heap_lang.heap_lang.bin_op]
95103
inductive BinOp where
96104
/- We use "tdiv" and "tmod" instead of "div" and "mod" to
97105
better match the behavior of 'real' languages:
@@ -104,6 +112,7 @@ inductive BinOp where
104112
deriving Inhabited, Repr, DecidableEq
105113

106114
mutual
115+
@[rocq_alias heap_lang.heap_lang.expr]
107116
inductive Exp : Type where
108117
/- values -/
109118
-- This constructor should not be used directly. Use Exp.ofVal instead.
@@ -138,6 +147,7 @@ mutual
138147
| newProph
139148
| resolve (e₀ e₁ e₂ : Exp)
140149
deriving Inhabited, Repr, DecidableEq
150+
@[rocq_alias heap_lang.heap_lang.val]
141151
inductive Val : Type where
142152
| lit (l : BaseLit)
143153
| rec_ (f x : Binder) (e : Exp)

Iris/Iris/ProofMode/Expr.lean

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,12 +156,13 @@ def Hyps.mkHyp {prop : Q(Type u)} (bi : Q(BI $prop))
156156
(name : Name) (ivar : IVarId) (p : Q(Bool)) (ty : Q($prop)) (e := q(iprop(□?$p $ty))) : Hyps bi e :=
157157
.hyp (mkIntuitionisticIf bi p (mkNameAnnotation name ivar ty)) name ivar p ty ⟨⟩
158158

159-
-- TODO: should this ensure that adding a hypothesis to emp creates a
160-
-- hyp node instead of a sep node?
161159
def Hyps.add {prop : Q(Type u)} (bi : Q(BI $prop))
162160
(name : Name) (ivar : IVarId) (p : Q(Bool)) (ty : Q($prop)) {e} (h : Hyps bi e)
163-
: Hyps bi q(iprop($e ∗ □?$p $ty)) :=
164-
Hyps.mkSep h (.mkHyp bi name ivar p ty)
161+
: (e' : Q($prop)) × Hyps bi e' × Q(iprop($e ∗ □?$p $ty ⊣⊢ $e')) :=
162+
match h with
163+
-- Adding a hypothesis to `emp` creates a `.hyp` node instead of a `.sep` node
164+
| .emp _ => ⟨_, .mkHyp bi name ivar p ty, q(emp_sep)⟩
165+
| _ => ⟨_, .mkSep h (.mkHyp bi name ivar p ty), q(.rfl)⟩
165166

166167
partial def parseHyps? {prop : Q(Type u)} (bi : Q(BI $prop)) (expr : Expr) :
167168
Option ((s : Q($prop)) × Hyps bi s) := do
@@ -552,6 +553,14 @@ def parseIrisGoal? (expr : Expr) : Option IrisGoal := do
552553
let ⟨e, hyps⟩ ← parseHyps? bi P
553554
some { u, prop, bi, e, hyps, goal }
554555

556+
/--
557+
Parse an Iris entailment (`Entails` rather than `Entails'`).
558+
-/
559+
def parseEntails? (expr : Expr) : Option <| Expr × Expr × Expr × Expr :=
560+
match expr.consumeMData.appM? ``Entails with
561+
| some #[prop, bi, e, goal] => some ⟨prop, bi, e, goal⟩
562+
| _ => none
563+
555564
def IrisGoal.toExpr : IrisGoal → Expr
556565
| { hyps, goal, .. } => q(Entails' $(hyps.tm) $goal)
557566

@@ -592,12 +601,12 @@ def Hyps.findWithInfo {u prop bi} (hyps : @Hyps u prop bi s) (name : Ident) : Me
592601
/-- Hyps.addWithInfo should be used by tactics that introduce a hypothesis based on the name given by the user. -/
593602
def Hyps.addWithInfo {prop : Q(Type u)} (bi : Q(BI $prop))
594603
(name : TSyntax ``binderIdent) (p : Q(Bool)) (ty : Q($prop)) {e} (h : Hyps bi e)
595-
: MetaM (IVarId × Hyps bi q(iprop($e ∗ □?$p $ty))) := do
604+
: MetaM (IVarId × (e' : Q($prop)) × Hyps bi e' × Q(iprop($e ∗ □?$p $ty ⊣⊢ $e'))) := do
596605
let ivar' ← mkFreshIVarId (isTrue p)
597606
let (nameTo, nameRef) ← getFreshName name
598607
addHypInfo nameRef nameTo ivar' prop ty (isBinder := true)
599-
let hyps := Hyps.add bi nameTo ivar' p ty h
600-
return ⟨ivar', hyps⟩
608+
let ⟨e', hyps, pf⟩ := Hyps.add bi nameTo ivar' p ty h
609+
return ⟨ivar', e', hyps, pf
601610

602611
/--
603612
Given hypothesis `hyps` representing `e` where every hypothesis exist in the
Lines changed: 53 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/-
22
Copyright (c) 2022 Lars König. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
4-
Authors: Lars König
4+
Authors: Lars König, Alvin Tang
55
-/
66
module
77

@@ -15,50 +15,77 @@ open Lean
1515
declare_syntax_cat icasesPat
1616
syntax icasesPatAlts := sepBy1(icasesPat, " | ")
1717
syntax binderIdent : icasesPat
18+
/-- Drop the hypothesis. -/
1819
syntax "-" : icasesPat
20+
/-- Frame the hypothesis and cancel it against the goal. -/
1921
syntax "$" : icasesPat
22+
/--
23+
Destruct a (separating) conjunction or existential; an existential variable is
24+
bound with `%x` where `x` is the name for it.
25+
-/
2026
syntax "⟨" icasesPatAlts,* "⟩" : icasesPat
27+
/-- Destruct a disjunction, one goal per disjunct. -/
2128
syntax "(" icasesPatAlts ")" : icasesPat
22-
syntax "%" binderIdent : icasesPat
29+
/-- Move the hypothesis to the pure Lean context and give it a name. -/
30+
syntax "%" rcasesPat : icasesPat
31+
/-- Move the hypothesis to the intuitionistic context and destruct the proposition. -/
2332
syntax "#" icasesPat : icasesPat
33+
/-- Move the hypothesis to the spatial context and destruct the proposition. -/
2434
syntax "∗" icasesPat : icasesPat
35+
/-- Eliminate the modality at the top of the hypothesis and destruct the remaining proposition. -/
2536
syntax ">" icasesPat : icasesPat
2637

27-
-- TODO: attach syntax to iCasesPat such that one can use withRef to
28-
-- associate the errors with the right part of the syntax
29-
inductive iCasesPat
38+
mutual
39+
40+
inductive iCasesPatCase
3041
| one (name : TSyntax ``binderIdent)
3142
| clear
3243
| frame
3344
| conjunction (args : List iCasesPat)
3445
| disjunction (args : List iCasesPat)
35-
| pure (pat : TSyntax ``binderIdent)
46+
| pure (pat : TSyntax `rcasesPat)
3647
| intuitionistic (pat : iCasesPat)
37-
| spatial (pat : iCasesPat)
38-
| mod (pat : iCasesPat)
48+
| spatial (pat : iCasesPat)
49+
| mod (pat : iCasesPat)
3950
deriving Repr, Inhabited
4051

52+
structure iCasesPat where
53+
ref : Syntax
54+
case : iCasesPatCase
55+
56+
end
57+
4158
partial def iCasesPat.parse (pat : TSyntax `icasesPat) : MacroM iCasesPat := do
42-
match go ⟨← expandMacros pat⟩ with
59+
let stx ← expandMacros pat
60+
match go ⟨stx⟩ with
4361
| none => Macro.throwUnsupported
4462
| some pat => return pat
4563
where
46-
go : TSyntax `icasesPat → Option iCasesPat
47-
| `(icasesPat| $name:binderIdent) => some <| .one name
48-
| `(icasesPat| -) => some <| .clear
49-
| `(icasesPat| $) => some <| .frame
50-
| `(icasesPat| ⟨$[$args],*⟩) => args.mapM goAlts |>.map (.conjunction ·.toList)
51-
| `(icasesPat| %$pat:binderIdent) => some <| .pure pat
52-
| `(icasesPat| #$pat) => go pat |>.map .intuitionistic
53-
| `(icasesPat| ∗$pat) => go pat |>.map .spatial
54-
| `(icasesPat| >$pat) => go pat |>.map .mod
55-
| `(icasesPat| ($pat)) => goAlts pat
56-
| _ => none
57-
goAlts : TSyntax ``icasesPatAlts → Option iCasesPat
58-
| `(icasesPatAlts| $args|*) =>
59-
match args.getElems with
60-
| #[arg] => go arg
61-
| args => args.mapM go |>.map (.disjunction ·.toList)
62-
| _ => none
64+
go (stx : TSyntax `icasesPat) : Option iCasesPat :=
65+
match stx.raw with
66+
-- delegate: keep the inner pattern's own ref
67+
| `(icasesPat| ($pat)) => goAlts pat
68+
| _ => (goCase stx).map ({ ref := stx.raw, case := · })
69+
70+
goCase (stx : TSyntax `icasesPat) : Option iCasesPatCase :=
71+
match stx.raw with
72+
| `(icasesPat| $name:binderIdent) => some <| .one name
73+
| `(icasesPat| -) => some <| .clear
74+
| `(icasesPat| $) => some <| .frame
75+
| `(icasesPat| ⟨$[$args],*⟩) => args.mapM goAlts |>.map (.conjunction ·.toList)
76+
| `(icasesPat| %$pat:rcasesPat) => some <| .pure pat
77+
| `(icasesPat| #$pat) => go pat |>.map <| .intuitionistic
78+
| `(icasesPat| ∗$pat) => go pat |>.map <| .spatial
79+
| `(icasesPat| >$pat) => go pat |>.map <| .mod
80+
| _ => none
81+
82+
goAlts (stx : TSyntax ``icasesPatAlts) : Option iCasesPat :=
83+
match stx with
84+
| `(icasesPatAlts| $args|*) =>
85+
match args.getElems with
86+
| #[arg] => go arg
87+
| args => args.mapM go |>.map
88+
fun ps => { ref := stx.raw, case := .disjunction ps.toList }
89+
| _ => none
6390

6491
end Iris.ProofMode

0 commit comments

Comments
 (0)