Theory Value
section‹Values›
text‹Our EFSM implementation can currently handle integers and strings. Here we define a sum type
which combines these. We also define an arithmetic in terms of values such that EFSMs do not need
to be strongly typed.›
theory Value
imports Trilean
begin
text_raw‹\snip{valuetype}{1}{2}{%›
datatype "value" = Num int | Str String.literal
text_raw‹}%endsnip›
fun is_Num :: "value ⇒ bool" where
"is_Num (Num _) = True" |
"is_Num (Str _) = False"
text_raw‹\snip{maybeIntArith}{1}{2}{%›
fun maybe_arith_int :: "(int ⇒ int ⇒ int) ⇒ value option ⇒ value option ⇒ value option" where
"maybe_arith_int f (Some (Num x)) (Some (Num y)) = Some (Num (f x y))" |
"maybe_arith_int _ _ _ = None"
text_raw‹}%endsnip›
lemma maybe_arith_int_not_None:
"maybe_arith_int f a b ≠ None = (∃n n'. a = Some (Num n) ∧ b = Some (Num n'))"
using maybe_arith_int.elims maybe_arith_int.simps(1) by blast
lemma maybe_arith_int_Some:
"maybe_arith_int f a b = Some (Num x) = (∃n n'. a = Some (Num n) ∧ b = Some (Num n') ∧ f n n' = x)"
using maybe_arith_int.elims maybe_arith_int.simps(1) by blast
lemma maybe_arith_int_None:
"(maybe_arith_int f a1 a2 = None) = (∄n n'. a1 = Some (Num n) ∧ a2 = Some (Num n'))"
using maybe_arith_int_not_None by blast
lemma maybe_arith_int_Not_Num:
"(∀n. maybe_arith_int f a1 a2 ≠ Some (Num n)) = (maybe_arith_int f a1 a2 = None)"
by (metis maybe_arith_int.elims option.distinct(1))
lemma maybe_arith_int_never_string: "maybe_arith_int f a b ≠ Some (Str x)"
using maybe_arith_int.elims by blast
definition "value_plus = maybe_arith_int (+)"
lemma value_plus_never_string: "value_plus a b ≠ Some (Str x)"
by (simp add: value_plus_def maybe_arith_int_never_string)
lemma value_plus_symmetry: "value_plus x y = value_plus y x"
apply (induct x y rule: maybe_arith_int.induct)
by (simp_all add: value_plus_def)
definition "value_minus = maybe_arith_int (-)"
lemma value_minus_never_string: "value_minus a b ≠ Some (Str x)"
by (simp add: maybe_arith_int_never_string value_minus_def)
definition "value_times = maybe_arith_int (*)"
lemma value_times_never_string: "value_times a b ≠ Some (Str x)"
by (simp add: maybe_arith_int_never_string value_times_def)
fun MaybeBoolInt :: "(int ⇒ int ⇒ bool) ⇒ value option ⇒ value option ⇒ trilean" where
"MaybeBoolInt f (Some (Num a)) (Some (Num b)) = (if f a b then true else false)" |
"MaybeBoolInt _ _ _ = invalid"
lemma MaybeBoolInt_not_num_1:
"∀n. r ≠ Some (Num n) ⟹ MaybeBoolInt f n r = invalid"
using MaybeBoolInt.elims by blast
definition value_gt :: "value option ⇒ value option ⇒ trilean" where
"value_gt a b ≡ MaybeBoolInt (>) a b"
fun value_eq :: "value option ⇒ value option ⇒ trilean" where
"value_eq None _ = invalid" |
"value_eq _ None = invalid" |
"value_eq (Some a) (Some b) = (if a = b then true else false)"
lemma value_eq_true: "(value_eq a b = true) = (∃x y. a = Some x ∧ b = Some y ∧ x = y)"
by (cases a; cases b, auto)
lemma value_eq_false: "(value_eq a b = false) = (∃x y. a = Some x ∧ b = Some y ∧ x ≠ y)"
by (cases a; cases b, auto)
lemma value_gt_true_Some: "value_gt a b = true ⟹ (∃x. a = Some x) ∧ (∃y. b = Some y)"
by (cases a; cases b, auto simp: value_gt_def)
lemma value_gt_true: "(value_gt a b = true) = (∃x y. a = Some (Num x) ∧ b = Some (Num y) ∧ x > y)"
apply (cases a)
using value_gt_true_Some apply blast
apply (cases b)
using value_gt_true_Some apply blast
subgoal for aa bb by (cases aa; cases bb, auto simp: value_gt_def)
done
lemma value_gt_false_Some: "value_gt a b = false ⟹ (∃x. a = Some x) ∧ (∃y. b = Some y)"
by (cases a; cases b, auto simp: value_gt_def)
end