Zulip Chat Archive
Stream: iris-lean
Topic: Why are sForall and sExists defined the way they are?
Markus de Medeiros (Mar 30 2025 at 11:42):
Anyone have any clue why sForall and sExists in BIBase are defined like
sForall : (PROP → Prop) → PROP
sExists : (PROP → Prop) → PROP
instead of the way it's done in König's thesis as well as Rocq Iris?
sForall {A} : (A → PROP) → PROP
sExists {A} : (A → PROP) → PROP
Mario Carneiro (Mar 30 2025 at 11:55):
The reason for this is because the type of {A} there is hidden and important
Mario Carneiro (Mar 30 2025 at 11:56):
it's {A : Type u}, and it causes a universe bump in BIBase and also restricts the usage of forall to that particular type universe
Mario Carneiro (Mar 30 2025 at 11:56):
this is actually a problem in iris as well, it's just more well hidden there because of the use of template universe polymorphism
Mario Carneiro (Mar 30 2025 at 11:57):
by using sets instead and defining indexed forall in terms of set forall, it's possible to get the best of both worlds: no universe bump and you can index over types in any universe, even larger than the BIBase itself
Mario Carneiro (Mar 30 2025 at 11:59):
We have analogous difficulties when defining complete lattices in mathlib
Markus de Medeiros (Mar 30 2025 at 12:00):
Okay, cool. Am I understanding correctly that the "set" in the "set forall" is analogous to image of the function in the "Rocq forall"?
Mario Carneiro (Mar 30 2025 at 12:00):
yes
Markus de Medeiros (Dec 01 2025 at 16:42):
For posterity: Here is a concrete #mwe demonstrating a universe problem present in the indexed representation that is not present in the set-based representation:
namespace Indexed
/- Indexed quantifiers -/
class BI (PROP : Type _) : Type _ where
iQuantifier {A : Type _} : (A → PROP) → PROP
#check BI -- Indexed.BI.{u_1, u_2} (PROP : Type u_1) : Type (max u_1 (u_2 + 1))
#check BI.iQuantifier -- Indexed.BI.iQuantifier.{u_1, u_2} {PROP : Type u_1} [self : BI PROP] {A : Type u_2} : (A → PROP) → PROP
variable (PROP : Type 3) [BI PROP]
variable (X : Type 2) (Y : Type 2) (d : X → PROP)
#check BI.iQuantifier (fun y : Y => BI.iQuantifier d)
-- Breaks when the universes for X and Y disagree
end Indexed
namespace Set
/- Set-based quantifiers -/
class BI (PROP : Type _) : Type _ where
sQuantifier : (PROP → Prop) → PROP
def BI.iQuantifier {PROP : Type _} [BI PROP] {ι : Type _} (I : ι → PROP) : PROP :=
BI.sQuantifier (fun P => ∃ i : ι, I i = P)
#check BI -- Set.BI.{u_1} (PROP : Type u_1) : Type u_1
#check BI.sQuantifier -- Set.BI.sQuantifier.{u_1} {PROP : Type u_1} [self : BI PROP] : (PROP → Prop) → PROP
#check BI.iQuantifier -- Set.BI.iQuantifier.{u_1, u_2} {PROP : Type u_1} [BI PROP] {ι : Type u_2} (I : ι → PROP) : PROP
variable (PROP : Type 1) [BI PROP]
variable (X : Type 2) (Y : Type 6) (d : X → PROP)
#check BI.iQuantifier (fun y : Y => BI.iQuantifier d)
-- Works no matter the universe levels for X, Y and PROP
end Set
Alex Bai (Dec 06 2025 at 20:05):
also FYI https://gitlab.mpi-sws.org/iris/iris/-/merge_requests/1111
Edwin Fernando (Jan 29 2026 at 22:09):
I am having some trouble trying to instantiate BIBase in a way I believe is because of iris-lean's sForall type (PROP → Prop) → PROP. I would like to keep the syntax and semantics of PROP (propositions in separation logic), separate. So an excerpt of my instantiation looks like
instance : BIBase (Assertion) where
Entails P Q := ∀ s : Store, ∀ : h Heap, P.denote s h → Q.denote s h
and := Assertion.and
where denote is a inductively defined on Assertion, defining the satsifiability relation giving semantics to the syntax of Assertions in separation logic. To be clear I define PROP := Assertion. I run into problems defining Assertion though for the sForall and sExists because of positivity.
inductive Assertion : Type
...
| sForall : (Ψ : Assertion → Prop) → Assertion
I want to note that the distinction between the syntax and semantics in Assertion seems standard in separation logic papers. But the classical separation logic example just directly provides the semantics in the BIBase instantiation. I might be able to do this as well which would avoid definition of (syntax) Assertion and the positivity violation entirely. But I don't think this is ideal, the code becomes difficult to write correctly and read, and the split between syntax and semantics aids in understanding of complicated separation logics.
And since sForall is more general than iForall, I'm unable to just define iForall in the syntax instead. I wanted to ask if there's some trivial workaround, whether you think this may be a disadvantage of sForall as (PROP → Prop) → PROP. Happy to provide more info on something in particular and I might just be making a silly mistake
Michael Sammler (Jan 30 2026 at 09:57):
Indeed, the BI interface assumes that you have impredicative quantification in your logic, which prevents syntactic assertions as far as I can tell. The standard in Iris is to use semantic assertions as shown by the classical separation logic example. I would recommend that you try the semantic approach. It has worked very well for complicated separation logics as shown by Iris / iProp.
Markus de Medeiros (Jan 30 2026 at 13:02):
@Remy Seassau did some work in this direction, maybe he could chime in?
Remy Seassau (Feb 02 2026 at 15:25):
Ah yes, we also ran into this issue
Remy Seassau (Feb 02 2026 at 15:29):
We ended up using a semantic definition of sForall to tie it to our syntactic definition of forall
Edwin Fernando (Feb 03 2026 at 15:00):
Thank you very much for the answers, and sorry for the late response.
Michael Sammler said:
Indeed, the BI interface assumes that you have impredicative quantification in your logic, which prevents syntactic assertions as far as I can tell. The standard in Iris is to use semantic assertions as shown by the classical separation logic example. I would recommend that you try the semantic approach. It has worked very well for complicated separation logics as shown by Iris / iProp.
Okay I didn't know the direct semantic way (henceforth I'll refer to as deep embedding) is standard and the syntax + semantics way (shallow embedding) is not generally possible. But I still want to try to figure it out to thoroughly understand the technical details. Also I want to note that I only want to use MoSeL, and not the whole of Iris, as that probably makes a difference.
I think there's a way around this impredicativity, by including in the syntax an sForall (lean) or iForall (rocq) constructor. This constructor takes as arguments semantics of other assertions. I think this is exactly what the below approach is
Remy Seassau said:
We ended up using a semantic definition of sForall to tie it to our syntactic definition of forall
I tried something like this already. And the problem I run into is violation of positivity (of inductive definitions).
(original definition)
inductive Assertion : List TyDet → List TyRand → Type
| iForall : ∀ {α}, (α → Assertion ds rs) → Assertion ds rs
(iris-lean's Set predicate definition)
inductive Assertion : List TyDet → List TyRand → Type
| sForall : (Assertion ds rs → Prop) → Assertion ds rs
The former compiles and the latter does not: arg #5 of 'Assertion.sForall' has a non positive occurrence of the datatypes being declared. So could you let me know what you had done @Remy Seassau , or just share me a link on GitHub perhaps so I could study an example?
Last updated: Feb 28 2026 at 14:05 UTC