Built with Alectryon, running Coq+SerAPI v8.15.0+0.15.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.

QRC1 in Coq: summary

This project is a formalization of the QRC1 logic defined in [1] and refined in [2]. This file lists the main definitions and results already formalized, linking them with the names and numbering of [2], with a side note on some results from [1].

[1] A. de Almeida Borges and J. J. Joosten (2020). Quantified Reflection Calculus with one modality. Advances in Modal Logic 13: 13-32. arXiv:2003.13651 [math.LO]

[2] A. de Almeida Borges and J. J. Joosten (2022). An escape from Vardanyan’s Theorem. Journal of Symbolic Logic. arXiv:2102.13091 [math.LO]

See the banner at the top for instructions on how to navigate this file.

From mathcomp Require Import all_ssreflect finmap.
Unset Printing Implicit Defensive.

Language

From QRC1 Require Import Language.

Variables are natural numbers.

VarName = nat : Set

A signature declares finitely many constants and predicate symbols.

Record signature : Type := Signature { ConstName : finType; PredName : finType; arity : PredName -> nat }. Arguments Signature ConstName [PredName] arity%function_scope

A term is either a variable or a constant.

Inductive term (sig : signature) : Type := Var : VarName -> term sig | Const : ConstName sig -> term sig. Arguments term sig Arguments Var sig _ Arguments Const [sig] _

A formula is either T, a predicate symbol applied to a tuple of terms, a conjunction of two other formulas, a diamond, or a universal quantifier.

Inductive formula (sig : signature) : Type := T : formula sig | Pred : forall P : PredName sig, (arity P).-tuple (term sig) -> formula sig | Conj : formula sig -> formula sig -> formula sig | Diam : formula sig -> formula sig | All : VarName -> formula sig -> formula sig. Arguments formula sig Arguments T sig Arguments Pred [sig P] _ Arguments Conj [sig] _ _ Arguments Diam [sig] _ Arguments All [sig] _ _

Formulas live within the qsp_scope (for quantified and strictly positive) and we provide the following notations.

Open Scope qsp_scope.
Notation "A /\ B" := (Conj A B) : qsp_scope (default interpretation) Notation "A /\ B" := (and A B) : type_scope
Notation "<> A" := (Diam A) : qsp_scope (default interpretation)

The free variables and constants of a formula are defined as usual, as is the definition of closed formula.

fv = fun sig : signature => fix fv (A : formula sig) : {fset VarName} := match A with | @T _ => fset0 | @Pred _ P ts => (\bigcup_(t <- ts) termfv t)%fset | B /\ C => (fv B `|` fv C)%fset | <> B => fv B | All x B => (fv B `\ x)%fset end : forall sig : signature, formula sig -> {fset VarName} Arguments fv [sig] A
constants = fun sig : signature => fix constants (A : formula sig) : {fset ConstName sig} := match A with | @T _ => fset0 | @Pred _ P ts => (\bigcup_(t <- ts) termconstants t)%fset | B /\ C => (constants B `|` constants C)%fset | <> B | All _ B => constants B end : forall sig : signature, formula sig -> {fset ConstName sig} Arguments constants [sig] A
closed = fun (sig : signature) (A : formula sig) => fv A == fset0 : forall sig : signature, formula sig -> bool Arguments closed [sig] A

The substitution of a term for a term is defined without regard for possible captures of the new term by existing quantifications.

sub = fun sig : signature => fix sub (A : formula sig) (t1 t2 : term sig) {struct A} : formula sig := match A with | @T _ => T sig | @Pred _ P ts => Pred [tuple of [seq (if ti == t1 then t2 else ti) | ti <- ts]] | B /\ C => sub B t1 t2 /\ sub C t1 t2 | <> B => <> sub B t1 t2 | All y B => if Var sig y == t1 then All y B else All y (sub B t1 t2) end : forall sig : signature, formula sig -> term sig -> term sig -> formula sig Arguments sub [sig] A t1 t2
Notation "A `[ t1 <- t2 ]" := (sub A t1 t2) : qsp_scope (default interpretation)

We then define the notion of a term being free for a variable or more generally a term in a formula, which protects against this case and is assumed as needed.

freefor = fun sig : signature => fix freefor (A : formula sig) (x : VarName) (t : term sig) {struct A} : bool := match A with | B /\ C => freefor B x t && freefor C x t | <> B => freefor B x t | All y B => (y == x) || freefor B x t && ((x \in fv B) ==> (y \notin termfv t)) | _ => true end : forall sig : signature, formula sig -> VarName -> term sig -> bool Arguments freefor [sig] A x t
freefort = fun sig : signature => fix freefort (A : formula sig) (t1 t2 : term sig) {struct A} : bool := match A with | B /\ C => freefort B t1 t2 && freefort C t1 t2 | <> B => freefort B t1 t2 | All y B => match t1 with | @Var _ x => (y == x) || freefort B (Var sig x) t2 && ((x \in fv B) ==> (y \notin termfv t2)) | Const c => freefort B (Const c) t2 && ((c \in constants B) ==> (y \notin termfv t2)) end | _ => true end : forall sig : signature, formula sig -> term sig -> term sig -> bool Arguments freefort [sig] A t1 t2

Finally we define three notions of complexity for qsp formulas (Definition 3.3).

modaldepth = fun sig : signature => fix modaldepth (A : formula sig) : nat := match A with | B /\ C => maxn (modaldepth B) (modaldepth C) | <> B => (modaldepth B).+1 | All _ B => modaldepth B | _ => 0 end : forall sig : signature, formula sig -> nat Arguments modaldepth [sig] A
quantifierdepth = fun sig : signature => fix quantifierdepth (A : formula sig) : nat := match A with | B /\ C => maxn (quantifierdepth B) (quantifierdepth C) | <> B => quantifierdepth B | All _ B => (quantifierdepth B).+1 | _ => 0 end : forall sig : signature, formula sig -> nat Arguments quantifierdepth [sig] A
depth = fun sig : signature => fix depth (A : formula sig) : nat := match A with | B /\ C => (maxn (depth B) (depth C)).+1 | <> B | All _ B => (depth B).+1 | _ => 0 end : forall sig : signature, formula sig -> nat Arguments depth [sig] A

QRC1

From QRC1 Require Import QRC1.

The definition of QRC1 proof (Definition 3.1).

Inductive QRC1Proof (sig : signature) : formula sig -> formula sig -> Prop := Top : forall A : formula sig, |- A ~> T sig | Same : forall A : formula sig, |- A ~> A | ConjEl : forall A B : formula sig, |- A /\ B ~> A | ConjEr : forall A B : formula sig, |- A /\ B ~> B | ConjI : forall A B C : formula sig, |- A ~> B -> |- A ~> C -> |- A ~> B /\ C | Cut : forall A B C : formula sig, |- A ~> B -> |- B ~> C -> |- A ~> C | Nec : forall A B : formula sig, |- A ~> B -> |- <> A ~> <> B | Trans : forall A : formula sig, |- <> (<> A) ~> <> A | AllIr : forall (x : nat_choiceType) (A B : formula sig), x \notin fv A -> |- A ~> B -> |- A ~> All x B | AllIl : forall (x : VarName) (t : term sig) (A B : formula sig), freefor A x t -> |- A`[Var sig x <- t] ~> B -> |- All x A ~> B | TermI : forall (x : VarName) (t : term sig) (A B : formula sig), freefor A x t -> freefor B x t -> |- A ~> B -> |- A`[Var sig x <- t] ~> B`[Var sig x <- t] | ConstE : forall (x : VarName) (c : ConstName sig) (A B : formula sig), c \notin constants A -> c \notin constants B -> |- A`[Var sig x <- Const c] ~> B`[Var sig x <- Const c] -> |- A ~> B. Arguments QRC1Proof [sig] _ _ Arguments Top [sig] A Arguments Same [sig] A Arguments ConjEl [sig] A B Arguments ConjEr [sig] A B Arguments ConjI [sig A B C] _ _ Arguments Cut [sig A B C] _ _ Arguments Nec [sig A B] _ Arguments Trans [sig] A Arguments AllIr [sig x A B] _ _ Arguments AllIl [sig x t A B] _ _ Arguments TermI [sig x t A B] _ _ _ Arguments ConstE [sig x c A B] _ _ _
Notation "|- A ~> B" := (QRC1Proof A B) : qsp_scope (default interpretation)

Lemma 3.2.

AllC : forall (sig : signature) (x y : VarName) (A : formula sig), |- All x (All y A) ~> All y (All x A)
All_sub : forall (sig : signature) (x : VarName) (t : term sig) (A : formula sig), freefor A x t -> |- All x A ~> A`[Var sig x <- t]
Diam_All : forall (sig : signature) (x : VarName) (A : formula sig), |- <> All x A ~> All x (<> A)
alphaconversion : forall (sig : signature) (x y : VarName) (A : formula sig), y \notin fv A -> freefor A x (Var sig y) -> |- All x A ~> All y A`[Var sig x <- Var sig y]
TermIr : forall (sig : signature) (x : VarName) (t : term sig) (A B : formula sig), x \notin fv A -> freefor B x t -> |- A ~> B -> |- A ~> B`[Var sig x <- t]
Const_AllIr : forall (sig : signature) (x : VarName) (c : ConstName sig) (A B : formula sig), x \notin fv A -> c \notin constants A -> c \notin constants B -> |- A ~> B`[Var sig x <- Const c] -> |- A ~> All x B

Lemma 3.4.

QRC1Proof_modaldepth : forall (sig : signature) (A B : formula sig), |- A ~> B -> modaldepth B <= modaldepth A
Diam_irreflexive : forall (sig : signature) (A : formula sig), ~ (|- A ~> <> A)

Kripke Semantics

From QRC1 Require Import KripkeSemantics.
Open Scope fset.

We only implement finite frames and models.

Not-necessarily adequate frames and models (Definition 4.1).

We stipulate that the worlds of a frame are a finite set of some choiceType named WType, and that the domain elements are a finite set of some choiceType named MType. This restricts the implemented definition of frame to finite frames, which is weaker than the definition presented in [1], but sufficient for the completeness proof.

We use the notions of rawFrame and rawModel to refer to possibly non adequate frames and models.

Unlike in [1], we define eta functions for every possible pair of worlds, which avoids unnecessary dependent types at the level of rawFrames.

Record rawFrame (WType MType : choiceType) : Type := RawFrame { world : {fset WType}; R : world -> world -> bool; domain : world -> {fset MType}; eta : forall w u : world, domain w -> domain u }. Arguments rawFrame WType MType Arguments RawFrame [WType MType world] R%function_scope [domain]%function_scope eta%function_scope
Record rawModel (sig : signature) (WType MType : choiceType) : Type := RawModel { rawFrame_of_rawModel : rawFrame WType MType; I : forall w : rawFrame_of_rawModel, ConstName sig -> domain w; J : forall (w : rawFrame_of_rawModel) (P : PredName sig), {fset (arity P).-tuple (domain w)} }. Arguments rawModel sig WType MType Arguments RawModel [sig WType MType rawFrame_of_rawModel] (I J)%function_scope

We can now define adequate frames and models (Definition 4.2).

Note that since we require eta functions for every pair of worlds, we require an additional property in order for a frame to be adequate, namely that all eta functions between a world and itself be the identity.

Record frame (WType MType : choiceType) : Type := Frame { rawFrame_of_frame : rawFrame WType MType; _ : is_true (adequateF rawFrame_of_frame) }. Arguments frame WType MType Arguments Frame [WType MType rawFrame_of_frame] _
adequateF = fun (WType MType : choiceType) (F : rawFrame WType MType) => [&& transitiveF F, transetaF F & idetaF F] : forall WType MType : choiceType, rawFrame WType MType -> bool Arguments adequateF [WType MType] F
transitiveFP : forall (WType MType : choiceType) (F : rawFrame WType MType), reflect (transitive (R (r:=F))) (transitiveF F)
transetaFP : forall (WType MType : choiceType) (F : rawFrame WType MType), reflect (forall (w u v : F) (d : domain w), R w u -> R u v -> eta v d = eta v (eta u d)) (transetaF F)
idetaFP : forall (WType MType : choiceType) (F : rawFrame WType MType), reflect (forall (w : F) (d : domain w), eta w d = d) (idetaF F)
Record model (sig : signature) (WType MType : choiceType) : Type := Model { rawModel_of_model : rawModel sig WType MType; _ : is_true (adequateM rawModel_of_model) }. Arguments model sig WType MType Arguments Model [sig WType MType rawModel_of_model] _
adequateM = fun (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) => adequateF M && concordantM M : forall (sig : signature) (WType MType : choiceType), rawModel sig WType MType -> bool Arguments adequateM [sig WType MType] M
concordantMP : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType), reflect (forall w u : M, R w u -> forall c : ConstName sig, val (I u c) = val (eta u (I w c))) (concordantM M)

An assignment is a function from variables to domain elements, parametrized on a world.

assignment = fun (WType MType : choiceType) (F : rawFrame WType MType) (w : F) => VarName -> domain w : forall (WType MType : choiceType) (F : rawFrame WType MType), F -> Type Arguments assignment [WType MType F] w

Assignments have a canonical extension to terms.

assignment_of_term = fun (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (w : M) (g : assignment w) (t : term sig) => match t with | @Var _ x => g x | Const c => I w c end : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (w : M), assignment w -> term sig -> domain w Arguments assignment_of_term [sig WType MType M w] g _
Unknown notation

A w-assignment can be lifted to a u-assignment by composing with eta u.

Again, we do not require that w R u as in [1], avoiding unwieldy dependent types at this stage. In practice, we will only rely on this notation when w R u does hold (see the definition of sat below).

Notation "g ` u" := (comp (eta u) g) (default interpretation)

Two assignments are X-alternative (or just x-alternative when X = {x}) when they agree on every variable except possibly those in X.

Xaltern = fun (WType MType : choiceType) (F : rawFrame WType MType) (w : F) (g h : assignment w) (X : {fset VarName}) => forall x : VarName, x \notin X -> g x = h x : forall (WType MType : choiceType) (F : rawFrame WType MType) (w : F), assignment w -> assignment w -> {fset VarName} -> Prop Arguments Xaltern [WType MType F w] g h X
xaltern = fun (WType MType : choiceType) (F : rawFrame WType MType) (w : F) (g h : assignment w) (x : VarName) => Xaltern g h [fset x] : forall (WType MType : choiceType) (F : rawFrame WType MType) (w : F), assignment w -> assignment w -> VarName -> Prop Arguments xaltern [WType MType F w] g h x

We now define the notion of satisfaction (Definition 4.3).

sat = fun (sig : signature) (WType MType : choiceType) => fix sat (M : rawModel sig WType MType) (w : M) (g : assignment w) (A : formula sig) {struct A} : Prop := match A with | @T _ => True | @Pred _ P ts => [tuple of [seq g`+ i | i <- ts]] \in J w P | B /\ C => (sat M w g B /\ sat M w g C)%type | <> B => exists u : M, (R w u /\ sat M u g`u B)%type | All x B => forall h : assignment w, xaltern g h x -> sat M w h B end : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (w : M), assignment w -> formula sig -> Prop Arguments sat [sig WType MType M w] g A

Kripke soundness

The soundness theorem (Theorem 4.4).

soundness : forall (sig : signature) (MType WType : choiceType) (A B : formula sig), |- A ~> B -> forall (M : model sig WType MType) (w : M) (g : assignment w), sat g A -> sat g B
Closed under the global context

The soundness proof is reasonably straightforward and as such is left out of [2]. However, it requires about 750 lines of extra definitions, lemmas, and proofs. We summarize those in what follows, following the soundness proof detailed in Section 4 of [1] arXiv:2003.13651 [math.LO].

Remark 4.5

sat_Xalternfv : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (w : M) (g h : assignment w) (X : {fset VarName}) (A : formula sig), Xaltern g h X -> [disjoint X & fv A] -> sat g A <-> sat h A

Lemma 4.6

substitution_formula : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (w : M) (g g' : assignment w) (x : VarName) (t : term sig) (A : formula sig), xaltern g g' x -> g' x = g`+ t -> freefor A x t -> sat g' A <-> sat g A`[Var sig x <- t]

Remark 4.7

Set Printing Implicit Defensive.
sat_noconstants : forall (sig : signature) (WType MType : choiceType) (F : rawFrame WType MType) (Ic Ic' : forall w : F, ConstName sig -> domain (r:=F) w) (J : forall (w : F) (P : PredName sig), {fset (arity (s:=sig) P).-tuple (domain (r:=F) w)}), let rM := {| rawFrame_of_rawModel := F; I := Ic; J := J |} in let rM' := {| rawFrame_of_rawModel := F; I := Ic'; J := J |} in forall (adeqM : adequateM rM) (adeqM' : adequateM rM') (w : F) (g : assignment (F:=F) w) (A : formula sig), (forall c : ConstName sig, c \in constants A -> Ic w c = Ic' w c) -> sat (M:=Model (rawModel_of_model:=rM) adeqM) (w:=w) g A <-> sat (M:=Model (rawModel_of_model:=rM') adeqM') (w:=w) g A
Unset Printing Implicit Defensive.

We now work towards frames restricted to some world r and all its successors. We follow a slightly different strategy than the one presented in [1], and as such the intermediate lemmas don't exactly match. The idea is to replace the interpretation of some constant c with some r-domain element d at the world r and by eta u d at every successor of r. Since this breaks the concordance of the model, we first drop every other world, obtaining a model that satisfies exactly the same formulas at r. Here the main difference is that we do not immediately drop the extra worlds; we keep them around and change the adequateness condition instead, so that it checks only r and its successors. We then proceed with this not entirely adequate model and only after the replacement is done do we drop the extra worlds and show that the resulting model is fully adequate. This strategy proved much easier to implement than dropping the extra worlds first.

The reflexive closure of R.

Rs = fun (WType MType : choiceType) (F : rawFrame WType MType) (w u : F) => (w == u) || R w u : forall (WType MType : choiceType) (F : rawFrame WType MType), F -> F -> bool Arguments Rs [WType MType F] _ _

A different notion of adequacy, that only checks a root world and its successors.

adequateFr = fun (WType MType : choiceType) (F : rawFrame WType MType) (r : F) => [&& transitiveFr r, transetaFr r & idetaFr r] : forall (WType MType : choiceType) (F : rawFrame WType MType), F -> bool Arguments adequateFr [WType MType F] r
transitiveFrP : forall (WType MType : choiceType) (F : rawFrame WType MType) (r : F), reflect (forall w u v : F, Rs r w -> R w u -> R u v -> R w v) (transitiveFr r)
transetaFrP : forall (WType MType : choiceType) (F : rawFrame WType MType) (r : F), reflect (forall (w u v : F) (d : domain w), Rs r w -> R w u -> R u v -> eta v d = eta v (eta u d)) (transetaFr r)
idetaFrP : forall (WType MType : choiceType) (F : rawFrame WType MType) (r : F), reflect (forall (w : F) (d : domain w), Rs r w -> eta w d = d) (idetaFr r)
adequateMr = fun (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M) => adequateFr r && concordantMr r : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType), M -> bool Arguments adequateMr [sig WType MType M] r
concordantMrP : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M), reflect (forall (w u : M) (c : ConstName sig), Rs r w -> R w u -> val (I u c) = val (eta u (I w c))) (concordantMr r)

An adequate frame is also adequate in the adequateFr sense, and the same for models.

frame_adequateFr : forall (WType MType : choiceType) (F : frame WType MType) (r : F), adequateFr r
model_adequateMr : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (r : M), adequateMr r

Given some interpretation I, a new interpretation that behaves as I except it interprets a given constant c as a given r-domain element d instead. This new interpretation will not lead to an adequate model unless r is the root (the concordance condition may fail).

replace_I = fun (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M) (c : ConstName sig) (d : domain r) (w : M) (c' : ConstName sig) => if c' == c then eta w d else I w c' : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M), ConstName sig -> domain r -> forall w : M, ConstName sig -> domain w Arguments replace_I [sig WType MType M r] c d w _
replace_rawModel = fun (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M) (c : ConstName sig) (d : domain r) => {| rawFrame_of_rawModel := M; I := replace_I c d; J := J (r:=M) |} : forall (sig : signature) (WType MType : choiceType) (M : rawModel sig WType MType) (r : M), ConstName sig -> domain r -> rawModel sig WType MType Arguments replace_rawModel [sig WType MType M r] c d
Set Printing Implicit Defensive.

We use the following notation to refer to raw models where the interpretation of c has been replaced by d on world r and its successors.

Notation "M `[ r , c <- d ]" := (replace_rawModel (M:=M) (r:=r) c d) (default interpretation)

A model replacing some constant interpretation with an element of the domain of r is adequate if ignoring every world that is not either r or its successor.

replace_adequateMr : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (r : M) (c : ConstName sig) (d : domain (r:=M) r), adequateMr (M:=M`[r, c <- d]) r

Changing the interpretation of a constant that does not appear in A is irrelevant.

sat_replace_noconstants : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (r w : M) (c : ConstName sig) (d : domain (r:=M) r) (g : assignment (F:=M) w) (A : formula sig), Rs (F:=M) r w -> c \notin constants A -> sat (M:=M) (w:=w) g A <-> sat (M:=M`[r, c <- d]) (w:=w) g A

Checking whether A is satisfied at world u is independent of which root is picked, as long as u is either the root or a successor of the root.

sat_replace_root : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (r w u : M) (c : ConstName sig) (d : domain (r:=M) r) (g : assignment (F:=M) u) (A : formula sig), Rs (F:=M) r w -> Rs (F:=M) w u -> sat (M:=M`[r, c <- d]) (w:=u) g A <-> sat (M:=M`[w, c <- eta (r:=M) (w:=r) w d]) (w:=u) g A

In particular, we can pick the world where we want to check A as the root.

sat_replace_root_self : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (r w : M) (c : ConstName sig) (d : domain (r:=M) r) (g : assignment (F:=M) w) (A : formula sig), Rs (F:=M) r w -> sat (M:=M`[r, c <- d]) (w:=w) g A <-> sat (M:=M`[w, c <- eta (r:=M) (w:=r) w d]) (w:=w) g A

A is satisfied at w in a model M iff A[x <- Const c] is satisfied at w in M with the interpretation of c replaced by the interpretation of x This is not quite Lemma 4.12 yet, because the new model is not adequate.

sat_replace : forall (sig : signature) (WType MType : choiceType) (M : model sig WType MType) (w : M) (c : ConstName sig) (x : VarName) (g : assignment (F:=M) w) (A : formula sig), c \notin constants A -> sat (M:=M) (w:=w) g A <-> sat (M:=M`[w, c <- g x]) (w:=w) g A`[Var sig x <- Const (sig:=sig) c]

We now start working toward actually drop the useless worlds.

A restricted set of worlds.

restrict_world = fun (MType WType : choiceType) (F : rawFrame WType MType) (r : F) => r |` [fset w in F | R (r:=F) r w] : forall (MType WType : choiceType) (F : rawFrame WType MType), F -> {fset F} Arguments restrict_world [MType] {WType} [F] r

We can now define restricted raw frames and raw models (Definition 4.8).

restrict_rawFrame = fun (MType WType : choiceType) (F : rawFrame WType MType) (r : F) => {| world := restrict_world (F:=F) r; R := restrict_R (F:=F) (r:=r); domain := restrict_domain (F:=F) (r:=r); eta := restrict_eta (F:=F) (r:=r) |} : forall (MType WType : choiceType) (F : rawFrame WType MType), F -> rawFrame [choiceType of F] MType Arguments restrict_rawFrame [MType] {WType} [F] r
restrict_R = fun (MType WType : choiceType) (F : rawFrame WType MType) (r : F) (w u : restrict_world (F:=F) r) => R (r:=F) (val w) (val u) : forall (MType WType : choiceType) (F : rawFrame WType MType) (r : F), restrict_world (F:=F) r -> restrict_world (F:=F) r -> bool Arguments restrict_R [MType] {WType} [F r] _ _
restrict_domain = fun (MType WType : choiceType) (F : rawFrame WType MType) (r : F) (w : restrict_world (F:=F) r) => domain (r:=F) (val w) : forall (MType WType : choiceType) (F : rawFrame WType MType) (r : F), restrict_world (F:=F) r -> {fset MType} Arguments restrict_domain [MType] {WType} [F r] _
restrict_eta = fun (MType WType : choiceType) (F : rawFrame WType MType) (r : F) (w u : restrict_world (F:=F) r) => eta (r:=F) (w:=val w) (val u) : forall (MType WType : choiceType) (F : rawFrame WType MType) (r : F) (w u : restrict_world (F:=F) r), restrict_domain (F:=F) (r:=r) w -> restrict_domain (F:=F) (r:=r) u Arguments restrict_eta [MType] {WType} [F r w] u _
restrict_rawModel = fun (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType) (r : M) => {| rawFrame_of_rawModel := restrict_rawFrame (F:=M) r; I := restrict_I (M:=M) (r:=r); J := restrict_J (M:=M) (r:=r) |} : forall (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType), M -> rawModel sig [choiceType of M] MType Arguments restrict_rawModel [sig MType] {WType} [M] r
restrict_I = fun (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType) (r : M) (w : restrict_world (F:=M) r) => I (r:=M) (val w) : forall (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType) (r : M) (w : restrict_world (F:=M) r), ConstName sig -> domain (r:=M) (val w) Arguments restrict_I [sig MType] {WType} [M r] w _
restrict_J = fun (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType) (r : M) (w : restrict_world (F:=M) r) => J (r:=M) (val w) : forall (sig : signature) (MType WType : choiceType) (M : rawModel sig WType MType) (r : M) (w : restrict_world (F:=M) r) (P : PredName sig), {fset (arity (s:=sig) P).-tuple (domain (r:=M) (val w))} Arguments restrict_J [sig MType] {WType} [M r] w P

Restricted raw frames and models are adequate in the normal sense (Remark 4.9).

restrict_frame_adequate : forall (MType WType : choiceType) (F : frame WType MType) (r : F), adequateF (restrict_rawFrame (F:=F) r)
restrict_model_adequate : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M), adequateM (restrict_rawModel (M:=M) r)

And thus we can define restricted frames and models.

restrict_frame = fun (MType WType : choiceType) (F : frame WType MType) (r : F) => Frame (rawFrame_of_frame:=restrict_rawFrame (F:=F) r) (restrict_frame_adequate (F:=F) r) : forall (MType WType : choiceType) (F : frame WType MType), F -> frame [choiceType of F] MType Arguments restrict_frame [MType] {WType} [F] r
restrict_model = fun (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M) => Model (rawModel_of_model:=restrict_rawModel (M:=M) r) (restrict_model_adequate (M:=M) r) : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType), M -> model sig [choiceType of M] MType Arguments restrict_model [sig MType] {WType} [M] r

Remark 4.10

sat_restrict : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M) (w : restrict_model (M:=M) r) (g : assignment (F:=restrict_model (M:=M) r) w) (A : formula sig), sat (M:=M) (w:=val w) g A <-> sat (M:=restrict_model (M:=M) r) (w:=w) g A

Restricting M`[r, c <- d] to r and its successors gives us an adequate model.

restrict_replace_adequate : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M) (c : ConstName sig) (d : domain (r:=M) r), adequateM (restrict_rawModel (M:=M`[r, c <- d]) r)

Definition 4.11

restrict_replace = fun (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M) (c : ConstName sig) (d : domain (r:=M) r) => Model (rawModel_of_model:=restrict_rawModel (M:=M`[r, c <- d]) r) (restrict_replace_adequate (M:=M) (r:=r) c d) : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (r : M), ConstName sig -> domain (r:=M) r -> model sig [choiceType of M] MType Arguments restrict_replace [sig MType] {WType} [M r] c d

We can finally prove the key lemma for the soundness of ConstE (Lemma 4.12).

sat_restrict_replace : forall (sig : signature) (MType WType : choiceType) (M : model sig WType MType) (w : M) (c : ConstName sig) (x : VarName) (g : assignment (F:=M) w) (A : formula sig), c \notin constants A -> sat (M:=M) (w:=w) g A <-> sat (M:=restrict_replace (M:=M) (r:=w) c (g x)) (w:=[` in_r_restrictr (F:=M) w]) g A`[Var sig x <- Const (sig:=sig) c]
Unset Printing Implicit Defensive.

Kripke completeness

From QRC1 Require Import Closure Pairs.

A pair is just a pair of finite sets of formulas.

pair = fun sig : signature => (formulas sig * formulas sig)%type : signature -> Type Arguments pair sig
formulas = fun sig : signature => {fset formula sig} : signature -> Type Arguments formulas sig

The notion of Phi-MCW is defined here as wfpair.

wfpair = fun (sig : signature) (fs : formulas sig) (p : pair sig) => [/\ p `<=` fs, closedfs p, consistent p, maximal fs p & witnessed p] : forall sig : signature, formulas sig -> pair sig -> Prop Arguments wfpair [sig] fs p
closedfs = fun (sig : signature) (fs : formulas sig) => all (closed (sig:=sig)) fs : forall sig : signature, formulas sig -> bool Arguments closedfs [sig] fs
consistent = fun (sig : signature) (p : pair sig) => forall B : formula sig, B \in p.- -> ~ (|- QRC1Equiv.bigConj sig p.+ ~> B) : forall sig : signature, pair sig -> Prop Arguments consistent [sig] p
maximalP : forall (sig : signature) (fs : formulas sig) (p : pair sig), reflect (forall A : formula sig, A \in fs -> A \in p.+ \/ A \in p.-) (maximal fs p)
witnessedP : forall (sig : signature) (p : pair sig), reflect (forall (x : VarName) (A : formula sig), All x A \in p.- -> exists c : ConstName sig, A`[Var sig x <- Const c] \in p.-) (witnessed p)

The closed closure of a formula is defined by induction on the depth of the formula (Definition 5.1). The closure of a set of formulas is the union of the closures of the individual formulas.

closure_eq : forall (sig : signature) (C : consts sig) (A : formula sig), closure C A = match A with | @T _ => [fset T sig] | @Pred _ P ts => [fset T sig; Pred ts] | A1 /\ A2 => (A1 /\ A2) |` closure C A1 `|` closure C A2 | <> B => <> B |` closure C B | All x B => All x B |` \bigcup_(c <- C) closure C B`[Var sig x <- Const c] end
closurefs = fun (sig : signature) (C : consts sig) (fs : formulas sig) => \bigcup_(A <- fs) closure C A : forall sig : signature, consts sig -> formulas sig -> formulas sig Arguments closurefs [sig] C fs

The number of different constants in a formula and the maximum of this value for a set of formulas (Definition 5.2).

constantcount = fun (sig : signature) (A : formula sig) => #|` constants A| : forall sig : signature, formula sig -> nat Arguments constantcount [sig] A
constantcountfs = fun (sig : signature) (fs : formulas sig) => \max_(A <- fs) constantcount A : forall sig : signature, formulas sig -> nat Arguments constantcountfs [sig] fs

Remark 5.3

constantcount_sub : forall (sig : signature) (x : VarName) (c : ConstName sig) (A : formula sig), constantcount A <= constantcount A`[Var sig x <- Const c] <= (constantcount A).+1
constantcount_closure : forall (sig : signature) (C : consts sig) (A : formula sig), constantcount A <= constantcountfs (closure C A) <= constantcount A + quantifierdepth A
constantcount_closurefs : forall (sig : signature) (C : consts sig) (fs : formulas sig), constantcountfs fs <= constantcountfs (closurefs C fs) <= constantcountfs fs + quantifierdepthfs fs

From now on we can no longer continue without classical logic. Thus we depend on the following axiom.

Classical_Prop.classic : forall P : Prop, P \/ ~ P

The Lindenbaum Lemma (Lemma 5.4)

lindenbaum : forall (sig : signature) (C : consts sig) (fs : formulas sig) (P : formula sig) (ns : formulas sig), constantsfs fs `<=` C -> closedfs fs -> (constantcountfs fs + quantifierdepthfs fs).*2 < #|` C| -> P \in closurefs C fs -> ns `<=` closurefs C fs -> consistent ([fset P], ns) -> exists2 q : pair sig, subpair ([fset P], ns) q && (modaldepthfs q.+ == modaldepth P) & wfpair (closurefs C fs) q
Axioms: Classical_Prop.classic : forall P : Prop, P \/ ~ P

We define RR as the target relation between worlds of the canonical model (Definition 5.5).

RRP : forall (sig : signature) (p q : pair sig), reflect ((forall A : formula sig, <> A \in p.- -> [fset A; <> A] `<=` q.-) /\ (exists A : formula sig, <> A \in p.+ `&` q.-)) (RR p q)

RR is transitive and irreflexive (when restricted to consistent pairs) (Lemma 5.6).

RR_trans : forall sig : signature, transitive (RR (sig:=sig))
RR_irr : forall (sig : signature) (p : pair sig), consistent p -> ~ RR p p

The pair existence lemma (Lemma 5.7)

pair_existence : forall (sig : signature) (C : consts sig) (fs : formulas sig) (p : pair sig) (P : formula sig), constantsfs fs `<=` C -> closedfs fs -> (constantcountfs fs + quantifierdepthfs fs).*2 < #|` C| -> wfpair (closurefs C fs) p -> <> P \in p.+ -> exists q : pair sig, [/\ wfpair (closurefs C fs) q, RR p q, P \in q.+ & modaldepthfs q.+ < modaldepthfs p.+]
Axioms: Classical_Prop.classic : forall P : Prop, P \/ ~ P

The formalization ends here for now. We aim to complete Section 5 in the future.