/- Port of `Language/Base.agda`. `StringSet` (built on `Lattice/MapSet.agda`, itself on `Lattice/Map.agda`) is lifted to mathlib's `Finset String`: `insertˢ ↦ insert`, `emptyˢ ↦ ∅`, `singletonˢ ↦ {·}`, `_⊔ˢ_ ↦ ∪`, `to-List ↦ Finset.toList` (with `Finset.nodup_toList` standing in for the intrinsic `Unique` proof). Constructor renaming (Agda mixfix has no direct Lean counterpart): _+_ ↦ Expr.add _-_ ↦ Expr.sub `_ ↦ Expr.var #_ ↦ Expr.num _←_ ↦ BasicStmt.assign noop ↦ BasicStmt.noop ⟨_⟩ ↦ Stmt.basic _then_ ↦ Stmt.andThen if_then_else_ ↦ Stmt.ifElse while_repeat_ ↦ Stmt.whileLoop The `_∈ᵉ_` / `_∈ᵇ_` variable-occurrence relations are ported as `Expr.HasVar` / `BasicStmt.HasVar`; the commented-out lemmas relating them to `Expr-vars` remain unported (they were commented out in the Agda, too). -/ import Mathlib.Data.Finset.Basic namespace Spa inductive Expr where | add (e₁ e₂ : Expr) | sub (e₁ e₂ : Expr) | var (x : String) | num (n : ℕ) deriving DecidableEq inductive BasicStmt where | assign (x : String) (e : Expr) | noop deriving DecidableEq inductive Stmt where | basic (bs : BasicStmt) | andThen (s₁ s₂ : Stmt) | ifElse (e : Expr) (s₁ s₂ : Stmt) | whileLoop (e : Expr) (s : Stmt) deriving DecidableEq /-- Agda: `_∈ᵉ_`. -/ inductive Expr.HasVar : String → Expr → Prop | addLeft {e₁ e₂ k} : Expr.HasVar k e₁ → Expr.HasVar k (.add e₁ e₂) | addRight {e₁ e₂ k} : Expr.HasVar k e₂ → Expr.HasVar k (.add e₁ e₂) | subLeft {e₁ e₂ k} : Expr.HasVar k e₁ → Expr.HasVar k (.sub e₁ e₂) | subRight {e₁ e₂ k} : Expr.HasVar k e₂ → Expr.HasVar k (.sub e₁ e₂) | here {k} : Expr.HasVar k (.var k) /-- Agda: `_∈ᵇ_`. -/ inductive BasicStmt.HasVar : String → BasicStmt → Prop | assignLeft {k e} : BasicStmt.HasVar k (.assign k e) | assignRight {k k' e} : Expr.HasVar k e → BasicStmt.HasVar k (.assign k' e) /-- Agda: `Expr-vars`. -/ def Expr.vars : Expr → Finset String | .add l r => l.vars ∪ r.vars | .sub l r => l.vars ∪ r.vars | .var s => {s} | .num _ => ∅ /-- Agda: `BasicStmt-vars`. -/ def BasicStmt.vars : BasicStmt → Finset String | .assign x e => {x} ∪ e.vars | .noop => ∅ /-- Agda: `Stmt-vars`. -/ def Stmt.vars : Stmt → Finset String | .basic bs => bs.vars | .andThen s₁ s₂ => s₁.vars ∪ s₂.vars | .ifElse e s₁ s₂ => (e.vars ∪ s₁.vars) ∪ s₂.vars | .whileLoop e s => e.vars ∪ s.vars /-- Agda: `Stmts-vars`. -/ def Stmt.varsList (ss : List Stmt) : Finset String := ss.foldr (fun s acc => s.vars ∪ acc) ∅ end Spa