section‹Converting Types to Strings and Back Again› theory ReadShow imports
Solidity_Symbex begin
text‹
In the following, we formalize a family of projection (and injection) functions for injecting
(projecting) basic types (i.e., @{type ‹nat›}, @{type ‹int›}, and @{type ‹bool›} in (out) of the
domains of strings. We provide variants for the two string representations of Isabelle/HOL, namely
@{type ‹string›} and @{type ‹String.literal›}. ›
subsubsection‹Bool› definition ‹Readbool s = (if s = ''True'' then True else False)› definition ‹Showbool b = (if b then ''True'' else ''False'')› definition ‹STR_is_bool s = (Showbool (Readbool s) = s)›
lemma Show_Read_bool_id: ‹STR_is_bool s ==> (Showbool (Readbool s) = s)› using STR_is_bool_def by fastforce
lemma STR_is_bool_split: ‹STR_is_bool s ==> s = ''False'' ∨ s = ''True''› by(auto simp: STR_is_bool_def Readbool_defShowbool_def)
lemma Read_Show_bool_id: ‹Readbool (Showbool b) = b› by(auto simp: Readbool_defShowbool_def)
definition ReadLbool::‹String.literal ==> bool› (‹⌊_⌋›) where ‹ReadLbool s = (if s = STR ''True'' then True else False)› definition ShowLbool:: ‹bool ==> String.literal› (‹⌈_⌉›) where ‹ShowLbool b = (if b then STR ''True'' else STR ''False'')› definition ‹strL_is_bool' s = (ShowLbool (ReadLbool s) = s)›
lemma true_neq_false[simp]: "ShowLbool True ≠ ShowLbool False" by (metis Read_Show_bool'_id)
subsubsection‹Natural Numbers›
definition nat_of_digit :: ‹char ==> nat›where ‹nat_of_digit c =
(if c = CHR ''0'' then 0
else if c = CHR ''1'' then 1
else if c = CHR ''2'' then 2
else if c = CHR ''3'' then 3
else if c = CHR ''4'' then 4
else if c = CHR ''5'' then 5
else if c = CHR ''6'' then 6
else if c = CHR ''7'' then 7
else if c = CHR ''8'' then 8
else if c = CHR ''9'' then 9
else undefined)›
declare nat_of_digit_def [solidity_symbex]
definition is_digit :: ‹char ==> bool›where ‹is_digit c =
(if c = CHR ''0'' then True
else if c = CHR ''1'' then True
else if c = CHR ''2'' then True
else if c = CHR ''3'' then True
else if c = CHR ''4'' then True
else if c = CHR ''5'' then True
else if c = CHR ''6'' then True
else if c = CHR ''7'' then True
else if c = CHR ''8'' then True
else if c = CHR ''9'' then True
else if c = CHR ''-'' then True
else False)›
definition digit_of_nat :: ‹nat ==> char›where ‹digit_of_nat x =
(if x = 0 then CHR ''0''
else if x = 1 then CHR ''1''
else if x = 2 then CHR ''2''
else if x = 3 then CHR ''3''
else if x = 4 then CHR ''4''
else if x = 5 then CHR ''5''
else if x = 6 then CHR ''6''
else if x = 7 then CHR ''7''
else if x = 8 then CHR ''8''
else if x = 9 then CHR ''9''
else undefined)›
lemma nat_explode'_digit: ‹hd (nat_explode' n ) < 10› proof(induct ‹n›) case0 thenshow ?caseby simp next case (Suc n) thenshow ?caseproof (cases ‹n < 9›) case True thenshow ?thesis by simp next case False thenshow ?thesis by simp qed qed
lemma div_ten_less: ‹n ≠ 0 ==> ((n::nat) div 10) < n› by simp
lemma unroll_nat_explode': ‹¬ n < 10 ==> (case n < 10 of True ==> [n mod 10] | False ==> n mod 10 # nat_explode' (n div 10)) =
(n mod 10 # nat_explode' (n div 10))› by simp
lemma nat_explode_mod_10_ident: ‹map (λ x. x mod 10) (nat_explode' n) = nat_explode' n› proof (cases ‹n < 10›) case True thenshow ?thesis by simp next case False thenshow ?thesis proof (induct ‹n› rule: nat_less_induct) case (1 n) note * = this thenshow ?case using div_ten_less apply(simp (no_asm)) using unroll_nat_explode'[of n] * by (smt (verit) list.simps(8) list.simps(9) mod_div_trivial mod_eq_self_iff_div_eq_0
nat_explode'.simps zero_less_numeral) qed qed
lemma nat_explode'_digits: ‹∀d ∈ set (nat_explode' n). d < 10› proof fix d assume‹d ∈ set (nat_explode' n)› thenhave‹d ∈ set (map (λm. m mod 10) (nat_explode' n))› by (simp only: nat_explode_mod_10_ident) thenshow‹d < 10› by auto qed
lemma nat_explode_digits: ‹∀d ∈ set (nat_explode n). d < 10› using nat_explode'_digits [of n] by (simp only: nat_explode_def set_rev)
lemma enumerate_suc: ‹enumerate (Suc n) l = map (λ (a,b). (a+1::nat,b)) (enumerate n l)› proof (induction‹l›) case Nil thenshow ?caseby simp next case (Cons a x) note * = this thenshow ?caseapply(simp only:enumerate_simps)
apply(simp only:‹enumerate (Suc n) x = map (λa. case a of (a, b) ==> (a + 1, b)) (enumerate n x)›[symmetric]) apply(simp) using * by (metis apfst_conv cond_case_prod_eta enumerate_Suc_eq) qed
subsubsection‹Integer› definition
Readint :: ‹string ==> int›where ‹Readint x = (if hd x = (CHR ''-'') then -(int (Readnat (tl x))) else int (Readnat x))›
definition Showint::‹int ==> string›where ‹Showint i = (if i < 0 then (CHR ''-'')#(Shownat (nat (-i)))
else Shownat (nat i))›
definition ‹STR_is_int s = (Showint (Readint s) = s)›
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.