theory Impl_Uv_Set imports "../../Iterator/Iterator" "../Intf/Intf_Set" "../../../Native_Word/Uint" begin subsection {* Bit-Vectors as Lists of Words *} subsubsection {* Lookup *} primrec lookup :: "nat => ('a::len) word list => bool" where "lookup _ [] <-> False" | "lookup n (w#ws) <-> (if n<len_of TYPE('a) then test_bit w n else lookup (n-len_of TYPE('a)) ws)" lemma lookup_append[simp]: "lookup n (w1@w2 :: 'a::len word list) <-> ( if n < len_of TYPE('a) * length w1 then lookup n w1 else lookup (n - len_of TYPE('a) * length w1) w2)" by (induction w1 arbitrary: n) auto lemma lookup_zeroes[simp]: "lookup i (replicate n (0::'a::len word)) = False" by (induction n arbitrary: i) auto lemma lookup_out_of_bound: fixes uv :: "'a::len word list" assumes "¬ i < len_of TYPE('a::len) * length uv" shows "¬ lookup i uv" using assms by (induction uv arbitrary: i) auto subsubsection {* Empty *} definition empty :: "'a::len word list" where "empty = []" subsubsection {* Set and Reset Bit *} function single_bit :: "nat => ('a::len) word list" where "single_bit n = ( if (n<len_of TYPE('a)) then [set_bit 0 n True] else 0#single_bit (n-len_of TYPE('a)))" by pat_completeness auto termination apply (relation "measure id") apply simp apply simp by (metis diff_less le0 lens_not_0(2) sup.semilattice_strict_iff_order) declare single_bit.simps[simp del] lemma lookup_single_bit[simp]: "lookup i ((single_bit n)::'a::len word list) <-> i = n" apply (induction n arbitrary: i rule: single_bit.induct) apply (subst single_bit.simps) apply (auto simp: bin_nth_sc_gen) done find_consts name: set_bit primrec set_bit :: "nat => 'a::len word list => 'a::len word list" where "set_bit i [] = single_bit i" | "set_bit i (w#ws) = ( if i<len_of TYPE('a) then bits_class.set_bit w i True # ws else w # set_bit (i - len_of TYPE('a)) ws)" lemma set_bit_lookup[simp]: "lookup i (set_bit j ws) <-> (lookup i ws ∨ i=j)" apply (induction ws arbitrary: i j) apply (auto simp: test_bit_set_gen word_size) done primrec reset_bit :: "nat => 'a::len word list => 'a::len word list" where "reset_bit i [] = []" | "reset_bit i (w#ws) = ( if i<len_of TYPE('a) then bits_class.set_bit w i False # ws else w # reset_bit (i - len_of TYPE('a)) ws)" lemma reset_bit_lookup[simp]: "lookup i (reset_bit j ws) <-> (lookup i ws ∧ i≠j)" apply (induction ws arbitrary: i j) apply (auto simp: test_bit_set_gen word_size) done subsubsection {* Binary Operations *} definition is_bin_op_impl :: "(bool=>bool=>bool) => ('a::len word => 'a::len word => 'a::len word) => bool" where "is_bin_op_impl f g ≡ (∀w v. ∀i<len_of TYPE('a). test_bit (g w v) i <-> f (test_bit w i) (test_bit v i))" definition "is_strict_bin_op_impl f g ≡ is_bin_op_impl f g ∧ f False False = False" fun binary :: "('a::len word => 'a::len word => 'a::len word) => 'a::len word list => 'a::len word list => 'a::len word list" where "binary f [] [] = []" | "binary f [] (w#ws) = f 0 w # binary f [] ws" | "binary f (v#vs) [] = f v 0 # binary f vs []" | "binary f (v#vs) (w#ws) = f v w # binary f vs ws" lemma binary_lookup: assumes "is_strict_bin_op_impl f g" shows "lookup i (binary g ws vs) <-> f (lookup i ws) (lookup i vs)" using assms apply (induction g ws vs arbitrary: i rule: binary.induct) apply (auto simp: is_strict_bin_op_impl_def is_bin_op_impl_def) done subsection {* Abstraction to Sets of Naturals *} definition "α uv ≡ {n. lookup n uv}" lemma memb_correct: "lookup i ws <-> i∈α ws" by (auto simp: α_def) lemma empty_correct: "α empty = {}" by (simp add: α_def empty_def) lemma single_bit_correct: "α (single_bit n) = {n}" by (simp add: α_def) lemma insert_correct: "α (set_bit i ws) = Set.insert i (α ws)" by (auto simp add: α_def) lemma delete_correct: "α (reset_bit i ws) = (α ws) - {i}" by (auto simp add: α_def) lemma binary_correct: assumes "is_strict_bin_op_impl f g" shows "α (binary g ws vs) = { i . f (i∈α ws) (i∈α vs) }" unfolding α_def by (auto simp add: binary_lookup[OF assms]) fun union :: "'a::len word list => 'a::len word list => 'a::len word list" where "union [] ws = ws" | "union vs [] = vs" | "union (v#vs) (w#ws) = (v OR w) # union vs ws" lemma union_lookup[simp]: fixes vs :: "'a::len word list" shows "lookup i (union vs ws) <-> lookup i vs ∨ lookup i ws" apply (induction vs ws arbitrary: i rule: union.induct) apply (auto simp: word_ao_nth) done lemma union_correct: "α (union ws vs) = α ws ∪ α vs" by (auto simp add: α_def) fun inter :: "'a::len word list => 'a::len word list => 'a::len word list" where "inter [] ws = []" | "inter vs [] = []" | "inter (v#vs) (w#ws) = (v AND w) # inter vs ws" lemma inter_lookup[simp]: fixes vs :: "'a::len word list" shows "lookup i (inter vs ws) <-> lookup i vs ∧ lookup i ws" apply (induction vs ws arbitrary: i rule: inter.induct) apply (auto simp: word_ao_nth) done lemma inter_correct: "α (inter ws vs) = α ws ∩ α vs" by (auto simp add: α_def) fun diff :: "'a::len word list => 'a::len word list => 'a::len word list" where "diff [] ws = []" | "diff vs [] = vs" | "diff (v#vs) (w#ws) = (v AND NOT w) # diff vs ws" lemma diff_lookup[simp]: fixes vs :: "'a::len word list" shows "lookup i (diff vs ws) <-> lookup i vs - lookup i ws" apply (induction vs ws arbitrary: i rule: diff.induct) apply (auto simp: word_ops_nth_size word_size) done lemma diff_correct: "α (diff ws vs) = α ws - α vs" by (auto simp add: α_def) fun zeroes :: "'a::len word list => bool" where "zeroes [] <-> True" | "zeroes (w#ws) <-> w=0 ∧ zeroes ws" lemma zeroes_lookup: "zeroes ws <-> (∀i. ¬lookup i ws)" apply (induction ws) apply (auto simp: word_eq_iff) by (metis diff_add_inverse2 not_add_less2) lemma isEmpty_correct: "zeroes ws <-> α ws = {}" by (auto simp: zeroes_lookup α_def) fun equal :: "'a::len word list => 'a::len word list => bool" where "equal [] [] <-> True" | "equal [] ws <-> zeroes ws" | "equal vs [] <-> zeroes vs" | "equal (v#vs) (w#ws) <-> v=w ∧ equal vs ws" lemma equal_lookup: fixes vs ws :: "'a::len word list" shows "equal vs ws <-> (∀i. lookup i vs = lookup i ws)" proof (induction vs ws rule: equal.induct) fix v w and vs ws :: "'a::len word list" assume IH: "equal vs ws = (∀i. lookup i vs = lookup i ws)" show "equal (v # vs) (w # ws) = (∀i. lookup i (v # vs) = lookup i (w # ws))" proof (rule iffI, rule allI) fix i assume "equal (v#vs) (w#ws)" thus "lookup i (v # vs) = lookup i (w # ws)" by (auto simp: IH) next assume "∀i. lookup i (v # vs) = lookup i (w # ws)" thus "equal (v # vs) (w # ws)" apply (auto simp: word_eq_iff IH) apply metis apply metis apply (drule_tac x="i + len_of TYPE('a)" in spec) apply auto [] apply (drule_tac x="i + len_of TYPE('a)" in spec) apply auto [] done qed qed (auto simp: zeroes_lookup) lemma equal_correct: "equal vs ws <-> α vs = α ws" by (auto simp: α_def equal_lookup) fun subseteq :: "'a::len word list => 'a::len word list => bool" where "subseteq [] ws <-> True" | "subseteq vs [] <-> zeroes vs" | "subseteq (v#vs) (w#ws) <-> (v AND NOT w = 0) ∧ subseteq vs ws" lemma subseteq_lookup: fixes vs ws :: "'a::len word list" shows "subseteq vs ws <-> (∀i. lookup i vs --> lookup i ws)" apply (induction vs ws rule: subseteq.induct) apply simp apply (auto simp: zeroes_lookup) [] apply (auto simp: word_ops_nth_size word_size word_eq_iff) by (metis diff_add_inverse2 not_add_less2) lemma subseteq_correct: "subseteq vs ws <-> α vs ⊆ α ws" by (auto simp: α_def subseteq_lookup) fun subset :: "'a::len word list => 'a::len word list => bool" where "subset [] ws <-> ¬zeroes ws" | "subset vs [] <-> False" | "subset (v#vs) (w#ws) <-> (if v=w then subset vs ws else subseteq (v#vs) (w#ws))" lemma subset_lookup: fixes vs ws :: "'a::len word list" shows "subset vs ws <-> ((∀i. lookup i vs --> lookup i ws) ∧ (∃i. ¬lookup i vs ∧ lookup i ws))" apply (induction vs ws rule: subset.induct) apply (simp add: zeroes_lookup) apply (simp add: zeroes_lookup) [] apply (simp del: subseteq_correct add: subseteq_lookup) apply safe apply simp_all apply (auto simp: word_ops_nth_size word_size word_eq_iff) done lemma subset_correct: "subset vs ws <-> α vs ⊂ α ws" by (auto simp: α_def subset_lookup) fun disjoint :: "'a::len word list => 'a::len word list => bool" where "disjoint [] ws <-> True" | "disjoint vs [] <-> True" | "disjoint (v#vs) (w#ws) <-> (v AND w = 0) ∧ disjoint vs ws" lemma disjoint_lookup: fixes vs ws :: "'a::len word list" shows "disjoint vs ws <-> (∀i. ¬(lookup i vs ∧ lookup i ws))" apply (induction vs ws rule: disjoint.induct) apply simp apply simp apply (auto simp: word_ops_nth_size word_size word_eq_iff) by (metis diff_add_inverse2 not_add_less2) lemma disjoint_correct: "disjoint vs ws <-> α vs ∩ α ws = {}" by (auto simp: α_def disjoint_lookup) subsection {* Lifting to Uint *} type_synonym uint_vector = "uint list" lift_definition uv_α :: "uint_vector => nat set" is α . lift_definition uv_lookup :: "nat => uint_vector => bool" is lookup . lift_definition uv_empty :: "uint_vector" is empty . lift_definition uv_single_bit :: "nat => uint_vector" is single_bit . lift_definition uv_set_bit :: "nat => uint_vector => uint_vector" is set_bit . lift_definition uv_reset_bit :: "nat => uint_vector => uint_vector" is reset_bit . lift_definition uv_union :: "uint_vector => uint_vector => uint_vector" is union . lift_definition uv_inter :: "uint_vector => uint_vector => uint_vector" is inter . lift_definition uv_diff :: "uint_vector => uint_vector => uint_vector" is diff . lift_definition uv_zeroes :: "uint_vector => bool" is zeroes . lift_definition uv_equal :: "uint_vector => uint_vector => bool" is equal . lift_definition uv_subseteq :: "uint_vector => uint_vector => bool" is subseteq . lift_definition uv_subset :: "uint_vector => uint_vector => bool" is subset . lift_definition uv_disjoint :: "uint_vector => uint_vector => bool" is disjoint . lemmas uv_memb_correct = memb_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_empty_correct = empty_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_single_bit_correct = single_bit_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_insert_correct = insert_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_delete_correct = delete_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_union_correct = union_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_inter_correct = inter_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_diff_correct = diff_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_isEmpty_correct = isEmpty_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_equal_correct = equal_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_subseteq_correct = subseteq_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_subset_correct = subset_correct[where 'a=dflt_size, Transfer.transferred] lemmas uv_disjoint_correct = disjoint_correct[where 'a=dflt_size, Transfer.transferred] lemmas [where 'a=dflt_size, Transfer.transferred, code] = lookup.simps empty_def single_bit.simps set_bit.simps reset_bit.simps union.simps inter.simps diff.simps zeroes.simps equal.simps subseteq.simps subset.simps disjoint.simps hide_const (open) α lookup empty single_bit set_bit reset_bit union inter diff zeroes equal subseteq subset disjoint subsection {* Autoref Setup *} definition uv_set_rel_def_internal: "uv_set_rel Rk ≡ if Rk=nat_rel then br uv_α (λ_. True) else {}" lemma uv_set_rel_def: "〈nat_rel〉uv_set_rel ≡ br uv_α (λ_. True)" unfolding uv_set_rel_def_internal relAPP_def by simp lemmas [autoref_rel_intf] = REL_INTFI[of "uv_set_rel" i_set] lemma uv_set_rel_sv[relator_props]: "single_valued (〈nat_rel〉uv_set_rel)" unfolding uv_set_rel_def by auto lemma uv_autoref[autoref_rules,param]: "(uv_lookup,op ∈) ∈ nat_rel -> 〈nat_rel〉uv_set_rel -> bool_rel" "(uv_empty,{}) ∈ 〈nat_rel〉uv_set_rel" "(uv_set_bit,insert) ∈ nat_rel -> 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel" "(uv_reset_bit,op_set_delete) ∈ nat_rel -> 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel" "(uv_union,op ∪) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel" "(uv_inter,op ∩) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel" "(uv_diff,op -) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel" "(uv_zeroes,op_set_isEmpty) ∈ 〈nat_rel〉uv_set_rel -> bool_rel" "(uv_equal,op =) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> bool_rel" "(uv_subseteq,op ⊆) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> bool_rel" "(uv_subset,op ⊂) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> bool_rel" "(uv_disjoint,op_set_disjoint) ∈ 〈nat_rel〉uv_set_rel -> 〈nat_rel〉uv_set_rel -> bool_rel" by (auto simp: uv_set_rel_def br_def simp: uv_memb_correct uv_empty_correct uv_insert_correct uv_delete_correct simp: uv_union_correct uv_inter_correct uv_diff_correct uv_isEmpty_correct simp: uv_equal_correct uv_subseteq_correct uv_subset_correct uv_disjoint_correct) export_code uv_lookup uv_empty uv_single_bit uv_set_bit uv_reset_bit uv_union uv_inter uv_diff uv_zeroes uv_equal uv_subseteq uv_subset uv_disjoint checking SML Scala Haskell? OCaml? end