Documentation

Core.ComputableTLAPlus.FreeVars

Metatheory for Expression.freeVars (defined in Subst.lean): membership lemmas that unfold freeVars's foldl (· ∪ ·) list cases to plain ∃ e ∈ es, …, plus the same freeVars vocabulary lifted over ComputableGuardedPlusCal.

x does not occur free in e — the freshness side condition every binder-introducing lemma needs.

Equations
Instances For
    theorem ComputableTLAPlus.Expression.not_mem_of_fresh {α : Type} {x : String} {inScope : List String} {e : Expression α} (fresh : xinScope) (sub : ze.freeVars, z inScope) :
    xe.freeVars

    If x avoids every name e could possibly read, x isn't one of them. The bridge from a scope-membership fact (WellFormedness.WellScoped's vocabulary) to an actual freshness fact (ExprSemantics.evalSubst's vocabulary): a with's bound name is fresh against inScope by construction, and a substituted-in expression's free variables are always a subset of inScope (it can only mention already-declared names), so the two never collide.

    Membership lemmas #

    freeVars's list cases fold (· ∪ ·) over es.attach.map (…); these unfold that fold to a plain ∃ e ∈ es, …, so evalLocal/evalSubst's inductions can move a memory-agreement hypothesis from a compound expression down to its components.

    theorem ComputableTLAPlus.Expression.mem_freeVars_set {α : Type} {z : String} {es : List (Expression α)} {τ : α} :
    z (set es τ).freeVars ees, z e.freeVars
    theorem ComputableTLAPlus.Expression.mem_freeVars_seq {α : Type} {z : String} {es : List (Expression α)} {τ : α} :
    z (seq es τ).freeVars ees, z e.freeVars
    theorem ComputableTLAPlus.Expression.mem_freeVars_tuple {α : Type} {z : String} {es : List (α × Expression α)} :
    z (tuple es).freeVars ees, z e.2.freeVars
    theorem ComputableTLAPlus.Expression.mem_freeVars_case {α : Type} {z : String} {bs : List (Expression α × Expression α)} {other : Option (Expression α)} {τ : α} :
    z (case bs other τ).freeVars (∃ bbs, z b.1.freeVars z b.2.freeVars) ∃ (e : Expression α), other = some e z e.freeVars
    theorem ComputableTLAPlus.Expression.mem_freeVars_except {α : Type} {z : String} {f : Expression α} {τ : α} {upds : List (List (String Expression α) × Expression α)} :
    z (f.except τ upds).freeVars z f.freeVars uupds, (∃ (e : Expression α), Sum.inr e u.1 z e.freeVars) z u.2.freeVars
    theorem ComputableTLAPlus.Expression.mem_freeVars_except_single {α : Type} {z : String} {f : Expression α} {τ : α} {path : List (String Expression α)} {rhs : Expression α} :
    z (f.except τ [(path, rhs)]).freeVars z f.freeVars (∃ (e : Expression α), Sum.inr e path z e.freeVars) z rhs.freeVars

    De Bruijn traversals #

    liftBound/openVar/close/subst/instantiate are each mapVars f 0 for a specific per-node f. freeVars_mapVars_subset bounds the free names of a mapVars result once — every other free-variable fact about those operations is a corollary.

    theorem ComputableTLAPlus.Expression.freeVars_mapVars_subset {α : Type} {f : αOriginSourceSpanExpression α} {S : Finset String} (hf : ∀ (k : ) (τ : α) (o : Origin) (pos : SourceSpan), z(f k τ o pos).freeVars, (z match o with | TypedTLAPlus.Origin.free n => {n} | x => ) z S) (k : ) (e : Expression α) {z : String} :
    z (mapVars f k e).freeVarsz e.freeVars z S

    Every free name of e.mapVars f k is either a free name f keeps at some .var _ (.free _) node of e, or a name in S — the extra set f may introduce at .bound nodes.

    liftBound shifts .bound indices and never touches a .free name.

    openVar turns the removed binder's index into the free name x, and moves no other name in or out.

    A name free in e.openVar x, other than x itself, was already free in e.

    theorem ComputableTLAPlus.Expression.freeVars_instantiate {α : Type} {args : List (Expression α)} {body : Expression α} {z : String} (hz : z (instantiate args body).freeVars) :
    z body.freeVars aargs, z a.freeVars

    A name free after instantiating the outermost binders is free in the body or in one of the instantiated arguments.

    theorem ComputableTLAPlus.Expression.subst_fresh {α : Type} {x : String} {e' : Expression α} (t : Expression α) :
    xt.freeVarssubst x e' t = t

    subst of a name not free in the target is the identity.

    theorem ComputableTLAPlus.Expression.subst_instantiate {α : Type} {x : String} {e' : Expression α} (hlc : e'.LC) {body : Expression α} (hbody : xbody.freeVars) (args : List (Expression α)) :
    subst x e' (instantiate args body) = instantiate (List.map (subst x e') args) body

    subst distributes over instantiate when the substituend is locally closed and the body is closed (Ξ.WellScoped gives operator bodies freeVars = ∅).

    Lifted over ComputableGuardedPlusCal — flat by construction (module doc, Core/GuardedPlusCal/Syntax.lean), so every Expr field is a direct component, not a nested Block: no well-founded recursion is needed here, unlike Expression.freeVars above.

    Every name a Ref's base variable and index expressions read. The base name itself is a use, same as any other Expression.var occurrence — a Ref is how a statement spells "read/write this variable", not a binder.

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For

      The base name is one of them — the {r.name} ∪ … above, named, so that a freshness hypothesis stated over a whole Ref yields the inequality against r.name that memory lemmas need.

      set's recipients are read in the enclosing scope; recipient then binds inside val, same shape as Expression.fn/.map'.

      Equations
      Instances For

        x is read nowhere in Br — precondition guard list (if any) and action block alike. The AtomicBranch-level freshness side condition the reorder_assign_guard pair needs: a preceding action's assigned name must stay fresh in every later guard for the substitution 𝒞_reord performs to be sound.

        Equations
        Instances For