79 lines
2.6 KiB
Lean4
79 lines
2.6 KiB
Lean4
|
|
/-
|
|||
|
|
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
|