* COMP4161 Assignment 3.
AutoCorres.AutoCorres
“HOL-Library.Prefix_Order”
section “Huffman Code”
(* The template for this question contains hints in the form of lemmas
that are not one of the direct questions a)-j). They are marked with
“oops”. You can, but do not have to prove these lemma. There is more
than one way to arrive at a correct proof.
The lemmas marked with sorry and TODO are the ones you should prove
unchanged for Q1. In Q2 you are allowed to tune the lemma statements.
type_synonym ‘a freq_list = “(‘a \
(* Q1 a): TODO *)
primrec add_one :: “‘a \
“add_one c [] = undefined” (* TODO *)
primrec freq_of :: “‘a list \
“freq_of [] = undefined” (* TODO *)
value “freq_of ”abcdaa””
lemma fst_set_add_one:
“fst ` set (add_one x xs) = {x} \
(* Q1 b): *)
lemma distinct_freq[simp]:
“distinct (map fst (freq_of cs))”
sorry (* TODO *)
datatype ‘a htree = Leaf ‘a int | Branch “‘a htree” “‘a htree”
primrec weight :: “‘a htree \
“weight (Leaf _ w) = w” |
“weight (Branch l r) = weight l + weight r”
fun build_tree :: “‘a htree list \
“build_tree [] = Leaf undefined 0” |
“build_tree [t] = t” |
“build_tree (t1 # t2 # cs) = build_tree (insort_key weight (Branch t1 t2) cs)”
definition huffman_tree :: “‘a freq_list \
“huffman_tree = build_tree o map (\
definition
“some_tree = huffman_tree (freq_of ”abcdaa”)”
value some_tree
type_synonym code = “bool list”
fun add_bit :: “bool \
“add_bit b (c, code) = (c, b # code)”
primrec code_list :: “‘a htree \
“code_list (Leaf c _) = [(c,[])]” |
“code_list (Branch l r) = map (add_bit False) (code_list l) @ map (add_bit True) (code_list r)”
definition code_map :: “‘a htree \
“code_map tree = map (\
value “code_list some_tree”
value “code_map some_tree”
(* Q1 c): TODO *)
definition encoder :: “(‘a \
“encoder mp xs = undefined” (* TODO *)
fun decoder :: “(code \
“decoder mp acs [] = []” |
“decoder mp acs (c#cs) = (if mp \
then the (mp # decoder mp [] cs
else decoder mp (acs @ [c]) cs)”
definition unique_prefix :: “(code \
“unique_prefix cm = (\
“is_inv mp mp’ = (\
lemma unique_prefixD:
“\
lemma decoder_step:
“\
\
(* Q1 d): *)
lemma decoder:
“\
\
sorry (* TODO *)
(* Q1 e): *)
lemma is_inv_map_of:
“\
is_inv (map_of xs) (map_of (map (\
sorry (* TODO *)
(* Q1 f): *)
primrec letters_of :: “‘a htree \
“letters_of (Leaf c _) = undefined” (* TODO: complete *)
(* Q1 g): *)
fun distinct_tree :: “‘a htree \
“distinct_tree (Leaf _ _) = undefined” (* TODO: complete *)
fun distinct_forest :: “‘a htree list \
“distinct_forest [] = True” |
“distinct_forest (t#ts) = (distinct_tree t \
letters_of t \
lemma fst_code_list:
“fst ` set (code_list t) = letters_of t”
(* Q1 h): *)
lemma distinct_fst_code_list[simp]:
“distinct_tree t \
sorry (* TODO *)
lemma distinct_forest_insort:
“distinct_forest (insort_key f t ts) =
(distinct_tree t \
lemma distinct_build_tree:
“distinct_forest ts \
lemma distinct_insort_map:
“distinct (map g (insort_key f x xs)) = (g x \
(* Q1 i): *)
lemma distinct_huffman[simp]:
“distinct (map fst fs) \
sorry (* TODO *)
(* If you’re curious, this would be the overall correctness statement.
You do not need to prove this one.
theorem huffman_decoder:
“\
decoder (map_of (code_map tree)) [] (encoder (map_of (code_list tree)) xs) = xs”
(* ———————————————————————————— *)
declare [[syntax_ambiguity_warning = false]]
definition “LEN = 1000”
declare LEN_def[simp]
external_file “stack.c”
install_C_file “stack.c”
autocorres “stack.c”
context stack
thm is_empty’_def
thm has_capacity’_def
thm push’_def
thm pop’_def
thm sum’_def
primrec stack_from :: “machine_word list \
“stack_from [] n s = (n = -1 )” |
“stack_from (x # xs) n s = (n < LEN \
definition is_stack where
“is_stack xs s \
(* Q2 a) *)
lemma is_stack_Nil_top[simp]:
“is_stack [] s = (top_” s = -1)”
sorry (* TODO *)
(* Q2 b) *)
lemma is_stack_Nil_is_empty:
“is_stack [] s = (is_empty’ s = 1)”
sorry (* TODO *)
(* Q2 c) *)
lemma stack_from_neg[simp]:
“stack_from xs (- 1) s = (xs = [])”
sorry (* TODO *)
(* Q2 d) *)
lemma is_stack_single:
“is_stack [x] s = (top_” s = 0 \
sorry (* TODO *)
(* Q2 e) *)
lemma is_stack_Cons[simp]:
“is_stack (x # xs) s =
(top_” s < LEN \
sorry (* TODO *)
(* Q2 f) *)
lemma stack_from_top_upd[simp]:
“stack_from xs n (s\
sorry (* TODO *)
(* Helper lemma — you can prove this one or state your own *)
lemma stack_from_top_and_array_upd’:
“\
stack_from xs n (s\
(* Q2 g) *)
lemma stack_from_top_and_array_upd[simp]:
“unat (n + 1) < LEN \
stack_from xs n (s\
stack_from xs n s”
sorry (* TODO *)
(* Q2 h) *)
lemma pop_correct_partial:
“\
sorry (* TODO *)
(* Q2 i) *)
lemma pop_correct_total:
“\
sorry (* TODO *)
(* Q2 j) *)
lemma push_correct_total:
“\
supply word_less_nat_alt[simp]
sorry (* TODO *)
(* Q2 k) *)
lemma sum_correct_partial:
“\
unfolding sum’_def
apply (subst whileLoop_add_inv[where
I=”TODO”])
sorry (* TODO *)