2026-06-09 19:30:42 -07:00
|
|
|
|
import Mathlib.Data.Finset.Basic
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-!
|
|
|
|
|
|
|
|
|
|
|
|
Base language.
|
|
|
|
|
|
|
|
|
|
|
|
This file defines the core object language for the program analysis and
|
|
|
|
|
|
transformation. It's a very basic imperative language. The `Spa/Language/Tagged/Basic.lean`
|
|
|
|
|
|
file provides an auto-derived version of the `Expr`, `BasicStmt`, and `Stmt` data
|
|
|
|
|
|
types with unique IDs per condtructor, enabling in-AST pointers.
|
|
|
|
|
|
|
|
|
|
|
|
-/
|
|
|
|
|
|
|
2026-06-09 19:30:42 -07:00
|
|
|
|
namespace Spa
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- A value-producing expression. Currently, this cannot have side effects. -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
inductive Expr where
|
|
|
|
|
|
| add (e₁ e₂ : Expr)
|
|
|
|
|
|
| sub (e₁ e₂ : Expr)
|
|
|
|
|
|
| var (x : String)
|
|
|
|
|
|
| num (n : ℕ)
|
|
|
|
|
|
deriving DecidableEq
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- A statement that cannot alter control flow (and thus, can be part of a basic block).
|
|
|
|
|
|
|
|
|
|
|
|
This differs from, e.g., a loop, which can cause execution to jump to its top several times. -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
inductive BasicStmt where
|
|
|
|
|
|
| assign (x : String) (e : Expr)
|
|
|
|
|
|
| noop
|
|
|
|
|
|
deriving DecidableEq
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- Any statements, which may or may not change program state (variable assignments). -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
inductive Stmt where
|
|
|
|
|
|
| basic (bs : BasicStmt)
|
|
|
|
|
|
| andThen (s₁ s₂ : Stmt)
|
|
|
|
|
|
| ifElse (e : Expr) (s₁ s₂ : Stmt)
|
|
|
|
|
|
| whileLoop (e : Expr) (s : Stmt)
|
|
|
|
|
|
deriving DecidableEq
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- Variables mentioned in this expression. -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
def Expr.vars : Expr → Finset String
|
|
|
|
|
|
| .add l r => l.vars ∪ r.vars
|
|
|
|
|
|
| .sub l r => l.vars ∪ r.vars
|
|
|
|
|
|
| .var s => {s}
|
|
|
|
|
|
| .num _ => ∅
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- Variables assigned or mentioned in this basic statement. -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
def BasicStmt.vars : BasicStmt → Finset String
|
|
|
|
|
|
| .assign x e => {x} ∪ e.vars
|
|
|
|
|
|
| .noop => ∅
|
|
|
|
|
|
|
2026-06-25 15:39:51 -05:00
|
|
|
|
/-- Variables assigned or mentioned in this statement. -/
|
2026-06-09 19:30:42 -07:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
end Spa
|