Allow negative numbers in expressions
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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).
|
||||||
|
|||||||
@@ -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₂ : ℤ) :
|
||||||
|
|||||||
Reference in New Issue
Block a user