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