Allow negative numbers in expressions

This commit is contained in:
2026-08-09 17:51:58 -05:00
parent a19f9fa148
commit c0542d0811
3 changed files with 23 additions and 8 deletions

View File

@@ -111,13 +111,16 @@ namespace SignAnalysis
variable (prog : Program) variable (prog : Program)
/-- The sign of an integer literal. -/
def signOf (z : ) : SignLattice :=
if z = 0 then .mk .zero else if 0 < z then .mk .plus else .mk .minus
def eval : Expr VariableValues SignLattice prog SignLattice def eval : Expr VariableValues SignLattice prog SignLattice
| .add e₁ e₂, vs => plus (eval e₁ vs) (eval e₂ vs) | .add e₁ e₂, vs => plus (eval e₁ vs) (eval e₂ vs)
| .sub e₁ e₂, vs => minus (eval e₁ vs) (eval e₂ vs) | .sub e₁ e₂, vs => minus (eval e₁ vs) (eval e₂ vs)
| .var k, vs => | .var k, vs =>
if h : FiniteMap.MemKey k vs then (FiniteMap.locate h).1 else .top if h : FiniteMap.MemKey k vs then (FiniteMap.locate h).1 else .top
| .num 0, _ => .mk .zero | .num z, _ => signOf z
| .num (_ + 1), _ => .mk .plus
lemma eval_mono (e : Expr) : Monotone (eval prog e) := by lemma eval_mono (e : Expr) : Monotone (eval prog e) := by
induction e with induction e with
@@ -139,7 +142,7 @@ lemma eval_mono (e : Expr) : Monotone (eval prog e) := by
dif_neg (fun hm => hk (FiniteMap.MemKey_iff.mp hm))] dif_neg (fun hm => hk (FiniteMap.MemKey_iff.mp hm))]
| num n => | num n =>
intro vs₁ vs₂ _ intro vs₁ vs₂ _
cases n <;> exact le_refl _ exact le_refl _
instance exprEvaluator : ExprEvaluator SignLattice prog := instance exprEvaluator : ExprEvaluator SignLattice prog :=
eval prog, eval_mono prog eval prog, eval_mono prog
@@ -159,6 +162,20 @@ private lemma int_neg_iff (z : ) : (∃ n : , z = -((n : ) + 1)) ↔ z
· rintro n, rfl; omega · rintro n, rfl; omega
· intro h; exact (-z - 1).toNat, by omega · intro h; exact (-z - 1).toNat, by omega
/-- `signOf` really does describe the literal it was computed from. -/
lemma interp_signOf (z : ) : signOf z (Value.int z) := by
unfold signOf
split
· case isTrue h => subst h; rfl
· rename_i hne
split
· case isTrue hpos =>
simp only [signInterpretation, interpSign, Value.int.injEq, int_pos_iff]
exact hpos
· case isFalse hnpos =>
simp only [signInterpretation, interpSign, Value.int.injEq, int_neg_iff]
omega
lemma plus_valid {g₁ g₂ : SignLattice} {z₁ z₂ : } lemma plus_valid {g₁ g₂ : SignLattice} {z₁ z₂ : }
(h₁ : g₁ (.int z₁)) (h₂ : g₂ (.int z₂)) : (h₁ : g₁ (.int z₁)) (h₂ : g₂ (.int z₂)) :
plus g₁ g₂ (.int (z₁ + z₂)) := by plus g₁ g₂ (.int (z₁ + z₂)) := by
@@ -184,9 +201,7 @@ instance eval_valid : ValidExprEvaluator SignLattice prog := by
| num n => | num n =>
intro _ intro _
show eval prog (.num n) vs (.int n) show eval prog (.num n) vs (.int n)
cases n with exact interp_signOf n
| zero => rfl
| succ n' => exact n', congrArg Value.int (by norm_cast)
| var x v hxv => | var x v hxv =>
intro hvs intro hvs
show eval prog (.var x) vs v show eval prog (.var x) vs v

View File

@@ -22,7 +22,7 @@ inductive Expr where
| add (e₁ e₂ : Expr) | add (e₁ e₂ : Expr)
| sub (e₁ e₂ : Expr) | sub (e₁ e₂ : Expr)
| var (x : String) | var (x : String)
| num (n : ) | num (z : )
deriving DecidableEq deriving DecidableEq
/-- A statement that cannot alter control flow (and thus, can be part of a basic block). /-- A statement that cannot alter control flow (and thus, can be part of a basic block).

View File

@@ -33,7 +33,7 @@ inductive Env.Mem : String × Value → Env → Prop
/-- Inference rules for evaluating an expression (`Spa.Expr`) in a given /-- Inference rules for evaluating an expression (`Spa.Expr`) in a given
environment. Pretty standard big-step expression evaluation. -/ environment. Pretty standard big-step expression evaluation. -/
inductive EvalExpr : Env Expr Value Prop inductive EvalExpr : Env Expr Value Prop
| num (ρ : Env) (n : ) : EvalExpr ρ (.num n) (.int n) | num (ρ : Env) (z : ) : EvalExpr ρ (.num z) (.int z)
| var (ρ : Env) (x : String) (v : Value) : | var (ρ : Env) (x : String) (v : Value) :
Env.Mem (x, v) ρ EvalExpr ρ (.var x) v Env.Mem (x, v) ρ EvalExpr ρ (.var x) v
| add (ρ : Env) (e₁ e₂ : Expr) (z₁ z₂ : ) : | add (ρ : Env) (e₁ e₂ : Expr) (z₁ z₂ : ) :