chapter {* Generated by Lem from word160.lem. *}

theory "Word160Auxiliary"

imports
 	 Main "~~/src/HOL/Library/Code_Target_Numeral"
	 "Lem_pervasives"
	 "Lem_word"
	 "Word160"

begin

(****************************************************)
(*                                                  *)
(* Lemmata                                          *)
(*                                                  *)
(****************************************************)

lemma bs_to_w160_def_lemma:
" ((\<forall> seq.
   W160 (integerFromBitSeq seq) =
     (\<lambda> w .  word_of_int (integerFromBitSeq w)) seq)) "
(* Theorem: bs_to_w160_def_lemma*)(* try *) by auto

lemma w160_to_bs_def_lemma:
" ((\<forall> i.
   bitSeqFromInteger (Some (( 160 :: nat))) i =
     (\<lambda> w .  bitSeqFromInteger (Some 160) ( (sint w))) (W160 i))) "
(* Theorem: w160_to_bs_def_lemma*)(* try *) by auto

lemma word160ToNat_def_lemma:
" ((\<forall> w.
   nat
     (abs
        (
           (integerFromBitSeq
              ((\<lambda> w .  bitSeqFromInteger (Some 160) ( (sint w))) w))))
     = unat w)) "
(* Theorem: word160ToNat_def_lemma*)(* try *) by auto

lemma word160ToInt_def_lemma:
" ((\<forall> w.

     (integerFromBitSeq
        ((\<lambda> w .  bitSeqFromInteger (Some 160) ( (sint w))) w)) =
     sint w)) "
(* Theorem: word160ToInt_def_lemma*)(* try *) by auto

lemma word160FromInteger_def_lemma:
" ((\<forall> i. W160 (i mod base) = (\<lambda> i .  word_of_int ( i)) i)) "
(* Theorem: word160FromInteger_def_lemma*)(* try *) by auto

lemma word160FromInt_def_lemma:
" ((\<forall> i. W160 ( i mod base) = word_of_int i)) "
(* Theorem: word160FromInt_def_lemma*)(* try *) by auto

lemma word160FromBoollist_def_lemma:
" ((\<forall> lst.
   (case  bitSeqFromBoolList lst of
         None => (\<lambda> w .  word_of_int (integerFromBitSeq w))
                   (bitSeqFromInteger None (( 0 :: int)))
     | Some a => (\<lambda> w .  word_of_int (integerFromBitSeq w)) a
   ) = of_bl lst)) "
(* Theorem: word160FromBoollist_def_lemma*)(* try *) by auto

lemma boolListFromWord160_def_lemma:
" ((\<forall> w.
   boolListFrombitSeq (( 160 :: nat))
     ((\<lambda> w .  bitSeqFromInteger (Some 160) ( (sint w))) w) =
   to_bl w)) "
(* Theorem: boolListFromWord160_def_lemma*)(* try *) by auto

lemma word160FromNumeral_def_lemma:
" ((\<forall> w. W160 (( w :: int) mod base) = ((word_of_int w) :: 160 word))) "
(* Theorem: word160FromNumeral_def_lemma*)(* try *) by auto

lemma w160Less_def_lemma:
" ((\<forall> bs1. \<forall> bs2.
   word160BinTest (op<) bs1 bs2 = word_sless bs1 bs2)) "
(* Theorem: w160Less_def_lemma*)(* try *) by auto

lemma w160LessEqual_def_lemma:
" ((\<forall> bs1. \<forall> bs2.
   word160BinTest (op \<le>) bs1 bs2 = word_sle bs1 bs2)) "
(* Theorem: w160LessEqual_def_lemma*)(* try *) by auto

lemma w160Greater_def_lemma:
" ((\<forall> bs1. \<forall> bs2.
   word160BinTest (op>) bs1 bs2 = word_sless bs2 bs1)) "
(* Theorem: w160Greater_def_lemma*)(* try *) by auto

lemma w160GreaterEqual_def_lemma:
" ((\<forall> bs1. \<forall> bs2.
   word160BinTest (op \<ge>) bs1 bs2 = word_sle bs2 bs1)) "
(* Theorem: w160GreaterEqual_def_lemma*)(* try *) by auto

lemma w160Compare_def_lemma:
" ((\<forall> bs1. \<forall> bs2.
   word160BinTest (genericCompare (op<) (op=)) bs1 bs2 =
     (genericCompare word_sless w160Eq bs1 bs2))) "
(* Theorem: w160Compare_def_lemma*)(* try *) by auto

lemma word160Negate_def_lemma:
" (( word160UnaryOp (\<lambda> i. - i) = (\<lambda> i. - i))) "
(* Theorem: word160Negate_def_lemma*)(* try *) by auto

lemma word160Succ_def_lemma:
" (( word160UnaryOp (\<lambda> n. n + ( 1 :: int)) = (\<lambda> n. n + 1))) "
(* Theorem: word160Succ_def_lemma*)(* try *) by auto

lemma word160Pred_def_lemma:
" (( word160UnaryOp (\<lambda> n. n - ( 1 :: int)) = (\<lambda> n. n - 1))) "
(* Theorem: word160Pred_def_lemma*)(* try *) by auto

lemma word160Lnot_def_lemma:
" (( word160UnaryOp integerLnot = (\<lambda> w. (NOT w)))) "
(* Theorem: word160Lnot_def_lemma*)(* try *) by auto

lemma word160Add_def_lemma:
" (( word160BinOp (op+) = (op+))) "
(* Theorem: word160Add_def_lemma*)(* try *) by auto

lemma word160Minus_def_lemma:
" (( word160BinOp (op-) = (op-))) "
(* Theorem: word160Minus_def_lemma*)(* try *) by auto

lemma word160Mult_def_lemma:
" (( word160BinOp (op*) = (op*))) "
(* Theorem: word160Mult_def_lemma*)(* try *) by auto

lemma word160IntegerDivision_def_lemma:
" (( word160BinOp (op div) = (op div))) "
(* Theorem: word160IntegerDivision_def_lemma*)(* try *) by auto

lemma word160Division_def_lemma:
" (( word160BinOp (op div) = (op div))) "
(* Theorem: word160Division_def_lemma*)(* try *) by auto

lemma word160Remainder_def_lemma:
" (( word160BinOp (op mod) = (op mod))) "
(* Theorem: word160Remainder_def_lemma*)(* try *) by auto

lemma word160Land_def_lemma:
" (( word160BinOp integerLand = (op AND))) "
(* Theorem: word160Land_def_lemma*)(* try *) by auto

lemma word160Lor_def_lemma:
" (( word160BinOp integerLor = (op OR))) "
(* Theorem: word160Lor_def_lemma*)(* try *) by auto

lemma word160Lxor_def_lemma:
" (( word160BinOp integerLxor = (op XOR))) "
(* Theorem: word160Lxor_def_lemma*)(* try *) by auto

lemma word160Min_def_lemma:
" (( word160BinOp (min) = min)) "
(* Theorem: word160Min_def_lemma*)(* try *) by auto

lemma word160Max_def_lemma:
" (( word160BinOp (max) = max)) "
(* Theorem: word160Max_def_lemma*)(* try *) by auto

lemma word160Power_def_lemma:
" (( word160NatOp (op^) = (op^))) "
(* Theorem: word160Power_def_lemma*)(* try *) by auto

lemma word160Asr_def_lemma:
" (( word160NatOp integerAsr = (op>>>))) "
(* Theorem: word160Asr_def_lemma*)(* try *) by auto

lemma word160Lsr_def_lemma:
" (( word160NatOp integerAsr = (op>>))) "
(* Theorem: word160Lsr_def_lemma*)(* try *) by auto

lemma word160Lsl_def_lemma:
" (( word160NatOp integerLsl = (op<<))) "
(* Theorem: word160Lsl_def_lemma*)(* try *) by auto

lemma word160UGT_def_lemma:
" ((\<forall> a. \<forall> b. (unat a > unat b) = a > b)) "
(* Theorem: word160UGT_def_lemma*)(* try *) by auto

end


theory Tut02
  imports "HOL-IMP.AExp" "HOL-IMP.BExp"
begin

fun deduplicate :: "'a list \<Rightarrow> 'a list"  where
  "deduplicate [] = []" |
  "deduplicate [x] = [x]" |
  "deduplicate (x#y#xs) = (if x = y then deduplicate (x#xs) else x # deduplicate (y#xs))"

value "deduplicate [1,1,2,3,2,2,1::nat] = [1,2,3,2,1]"

lemma "length (deduplicate xs) \<le> length xs"
  by(induction xs rule: deduplicate.induct, auto)

fun subst :: "vname \<Rightarrow> aexp \<Rightarrow> aexp \<Rightarrow> aexp"  where
  "subst x a' (N n) = (N n)" |
  "subst x a' (V v) = (if x = v then a' else V v)" |
  "subst x a' (Plus i j) = Plus (subst x a' i) (subst x a' j)"

lemma subst_

lemma comp: "aval a1 s = aval a2 s \<Longrightarrow> aval (subst x a1 a) s = aval (subst x a2 a) s"
  by(induction a arbitrary: x a1 a2 s, auto)

datatype aexp' = N' int | V' vname | Plus' aexp' aexp' | PI' vname

fun aval' :: "aexp' \<Rightarrow> state \<Rightarrow> (val \<times> state)" where
  "aval' (N' n) s = (n, s)" |
  "aval' (V' v) s = (s v, s)" |
  "aval' (Plus' i j) s = (
    let (i', s) = aval' i s;
    (j', s) = aval' j s
    in (i' + j', s))" |
  "aval' (PI' v) s = (s v, s(v := (s v) + 1))"

value "<>(x := 0)"
value "aval' (Plus' (PI' ''x'') (V' ''x'')) <>"
value "aval' (Plus' (Plus' (PI' ''x'') (PI' ''x'')) (PI' ''x'')) <>"

lemma aval'_PI'_inc:
  "aval' (PI' v) s = (r, s') \<Longrightarrow> s x \<le> s' x"
  by auto

lemma aval'_mono:
  "aval' a s = (r, s') \<Longrightarrow> s x \<le> s' x"
  by(induction a arbitrary: s r s', auto split: prod.splits, fastforce)

lemma aval'_inc:
  "aval' a <> = (v, s') \<Longrightarrow> 0 \<le> s' x"
  unfolding null_state_def using aval'_mono by fastforce

end


(*  Title:      HOL/HOLCF/Library/Bool_Discrete.thy
    Author:     Brian Huffman
*)

section \<open>Discrete cpo instance for booleans\<close>

theory Bool_Discrete
imports HOLCF
begin

text \<open>Discrete cpo instance for \<^typ>\<open>bool\<close>.\<close>

instantiation bool :: discrete_cpo
begin

definition below_bool_def:
  "(x::bool) \<sqsubseteq> y \<longleftrightarrow> x = y"

instance proof
qed (rule below_bool_def)

end

text \<open>
  TODO: implement a command to automate discrete predomain instances.
\<close>

instantiation bool :: predomain
begin

definition
  "(liftemb :: bool u \<rightarrow> udom u) \<equiv> liftemb oo u_map\<cdot>(\<Lambda> x. Discr x)"

definition
  "(liftprj :: udom u \<rightarrow> bool u) \<equiv> u_map\<cdot>(\<Lambda> y. undiscr y) oo liftprj"

definition
  "liftdefl \<equiv> (\<lambda>(t::bool itself). LIFTDEFL(bool discr))"

instance proof
  show "ep_pair liftemb (liftprj :: udom u \<rightarrow> bool u)"
    unfolding liftemb_bool_def liftprj_bool_def
    apply (rule ep_pair_comp)
    apply (rule ep_pair_u_map)
    apply (simp add: ep_pair.intro)
    apply (rule predomain_ep)
    done
  show "cast\<cdot>LIFTDEFL(bool) = liftemb oo (liftprj :: udom u \<rightarrow> bool u)"
    unfolding liftemb_bool_def liftprj_bool_def liftdefl_bool_def
    apply (simp add: cast_liftdefl cfcomp1 u_map_map)
    apply (simp add: ID_def [symmetric] u_map_ID)
    done
qed

end

lemma cont2cont_if [simp, cont2cont]:
  assumes b: "cont b" and f: "cont f" and g: "cont g"
  shows "cont (\<lambda>x. if b x then f x else g x)"
by (rule cont_apply [OF b cont_discrete_cpo], simp add: f g)

lemma cont2cont_eq [simp, cont2cont]:
  fixes f g :: "'a::cpo \<Rightarrow> 'b::discrete_cpo"
  assumes f: "cont f" and g: "cont g"
  shows "cont (\<lambda>x. f x = g x)"
apply (rule cont_apply [OF f cont_discrete_cpo])
apply (rule cont_apply [OF g cont_discrete_cpo])
apply (rule cont_const)
done

end