diff --git a/isabelle/2021/HSV_tasks_2021.thy b/isabelle/2021/HSV_tasks_2021.thy new file mode 100644 index 0000000..2e56627 --- /dev/null +++ b/isabelle/2021/HSV_tasks_2021.thy @@ -0,0 +1,179 @@ +theory HSV_tasks_2021 imports Complex_Main begin + +section \Task 1: Factorising circuits.\ + +(* Datatype for representing simple circuits. *) +datatype "circuit" = + NOT "circuit" +| AND "circuit" "circuit" +| OR "circuit" "circuit" +| TRUE +| FALSE +| INPUT "int" + +(* Simulates a circuit given a valuation for each input wire. *) +fun simulate where + "simulate (AND c1 c2) \ = ((simulate c1 \) \ (simulate c2 \))" +| "simulate (OR c1 c2) \ = ((simulate c1 \) \ (simulate c2 \))" +| "simulate (NOT c) \ = (\ (simulate c \))" +| "simulate TRUE \ = True" +| "simulate FALSE \ = False" +| "simulate (INPUT i) \ = \ i" + +(* Equivalence between circuits. *) +fun circuits_equiv (infix "\" 50) (* the "50" indicates the operator precedence *) where + "c1 \ c2 = (\\. simulate c1 \ = simulate c2 \)" + +(* An optimisation that exploits the following Boolean identities: + `(a | b) & (a | c) = a | (b & c)` + `(a | b) & (c | a) = a | (b & c)` + `(a | b) & (b | c) = b | (a & c)` + `(a | b) & (c | b) = b | (a & c)` + *) +fun factorise where + "factorise (NOT c) = NOT (factorise c)" +| "factorise (AND (OR c1 c2) (OR c3 c4)) = ( + let c1' = factorise c1; c2' = factorise c2; c3' = factorise c3; c4' = factorise c4 in + if c1' = c3' then OR c1' (AND c2' c4') + else if c1' = c4' then OR c1' (AND c2' c3') + else if c2' = c3' then OR c2' (AND c1' c4') + else if c2' = c4' then OR c2' (AND c1' c3') + else AND (OR c1' c2') (OR c3' c4'))" +| "factorise (AND c1 c2) = AND (factorise c1) (factorise c2)" +| "factorise (OR c1 c2) = OR (factorise c1) (factorise c2)" +| "factorise TRUE = TRUE" +| "factorise FALSE = FALSE" +| "factorise (INPUT i) = INPUT i" + +lemma (* test case *) + "factorise (AND TRUE TRUE) = AND TRUE TRUE" + by eval +lemma (* test case *) + "factorise (AND (OR (INPUT 1) FALSE) (OR TRUE (INPUT 1))) = + OR (INPUT 1) (AND FALSE TRUE)" + by eval +lemma (* test case *) + "factorise (NOT (AND (OR FALSE (INPUT 2)) (OR TRUE (INPUT 2)))) = + NOT (OR (INPUT 2) (AND FALSE TRUE))" + by eval + +theorem factorise_is_sound: "factorise c \ c" + sorry + +fun factorise2 where "factorise2 c = c" (* dummy definition *) + +lemma (* test case *) + "factorise2 (OR (AND (INPUT 1) (INPUT 2)) (AND TRUE (INPUT 1))) = + AND (INPUT 1) (OR (INPUT 2) TRUE)" + sorry + +theorem factorise2_is_sound: "factorise2 c \ c" + sorry + +section \Task 2: A theorem about divisibility.\ + +(* NB: Without the "::int" annotation, Isabelle will try to prove a + slightly more general theorem where "a" and "b" can be either ints + or nats. That more general theorem is a little harder to prove. *) +theorem plus_dvd_odd_power: + "(a::int) + b dvd a ^ (2 * n + 1) + b ^ (2 * n + 1)" + sorry + + +section \Task 3: Proving that the shift-and-add-3 algorithm is correct.\ + +subsection \Binary and its conversion to nat\ + +type_synonym bit = "bool" + +abbreviation B0 where "B0 == False" +abbreviation B1 where "B1 == True" + + +fun binary_to_nat :: "bit list \ nat" +where + "binary_to_nat [] = 0" +| "binary_to_nat (b # bs) = (if b then 2 ^ length bs else 0) + binary_to_nat bs" + + +lemma (* test case *) "binary_to_nat [B0, B1, B0, B1] = 5" by eval +lemma (* test case *) "binary_to_nat [B0, B0, B1, B0, B1] = 5" by eval +lemma (* test case *) "binary_to_nat [B1] = 1" by eval +lemma (* test case *) "binary_to_nat [B0] = 0" by eval + +subsection \BCD and its conversion to nat\ + +type_synonym nibble = "bit * bit * bit * bit" + +fun nibble_to_nat :: "nibble \ nat" +where + "nibble_to_nat (B0,B0,B0,B0) = 0" +| "nibble_to_nat (B0,B0,B0,B1) = 1" +| "nibble_to_nat (B0,B0,B1,B0) = 2" +| "nibble_to_nat (B0,B0,B1,B1) = 3" +| "nibble_to_nat (B0,B1,B0,B0) = 4" +| "nibble_to_nat (B0,B1,B0,B1) = 5" +| "nibble_to_nat (B0,B1,B1,B0) = 6" +| "nibble_to_nat (B0,B1,B1,B1) = 7" +| "nibble_to_nat (B1,B0,B0,B0) = 8" +| "nibble_to_nat (B1,B0,B0,B1) = 9" +| "nibble_to_nat (B1,B0,B1,B0) = 10" +| "nibble_to_nat (B1,B0,B1,B1) = 11" +| "nibble_to_nat (B1,B1,B0,B0) = 12" +| "nibble_to_nat (B1,B1,B0,B1) = 13" +| "nibble_to_nat (B1,B1,B1,B0) = 14" +| "nibble_to_nat (B1,B1,B1,B1) = 15" + +fun bcd_to_nat :: "nibble list \ nat" +where + "bcd_to_nat [] = 0" +| "bcd_to_nat (n # ns) = bcd_to_nat ns + nibble_to_nat n * 10 ^ length ns" + +lemma (* test case *) "bcd_to_nat [(B0,B1,B1,B0)] = 6" by eval +lemma (* test case *) "bcd_to_nat [(B0,B1,B1,B0),(B1,B0,B0,B1)] = 69" by eval +lemma (* test case *) "bcd_to_nat [(B0,B0,B0,B0),(B1,B0,B0,B1)] = 9" by eval +lemma (* test case *) "bcd_to_nat [(B0,B0,B1,B1),(B0,B0,B0,B0)] = 30" by eval + + +subsection \Converting binary to BCD\ + +fun binary_to_bcd :: "bit list \ nibble list" +where + "binary_to_bcd bs = []" (* dummy definition *) + +lemma (* test case *) + "binary_to_bcd [B1,B0,B1,B0,B1,B0,B1] = [(B1,B0,B0,B0), (B0,B1,B0,B1)]" + sorry + +subsection \Checking that nibbles correspond to valid BCD digits\ + +fun valid_nibble :: "nibble \ bool" +where + "valid_nibble (B0,B0,B0,B0) = True" +| "valid_nibble (B0,B0,B0,B1) = True" +| "valid_nibble (B0,B0,B1,B0) = True" +| "valid_nibble (B0,B0,B1,B1) = True" +| "valid_nibble (B0,B1,B0,B0) = True" +| "valid_nibble (B0,B1,B0,B1) = True" +| "valid_nibble (B0,B1,B1,B0) = True" +| "valid_nibble (B0,B1,B1,B1) = True" +| "valid_nibble (B1,B0,B0,B0) = True" +| "valid_nibble (B1,B0,B0,B1) = True" +| "valid_nibble (B1,B0,B1,B0) = False" +| "valid_nibble (B1,B0,B1,B1) = False" +| "valid_nibble (B1,B1,B0,B0) = False" +| "valid_nibble (B1,B1,B0,B1) = False" +| "valid_nibble (B1,B1,B1,B0) = False" +| "valid_nibble (B1,B1,B1,B1) = False" + +theorem binary_to_bcd_valid: + "list_all valid_nibble (binary_to_bcd bs)" + sorry + +subsection \Proof that the binary_to_bcd translation is correct.\ + +theorem binary_to_bcd_correct: + "bcd_to_nat (binary_to_bcd bs) = binary_to_nat bs" + sorry + +end \ No newline at end of file diff --git a/isabelle/2021/isabelle_exercises_2021.pdf b/isabelle/2021/isabelle_exercises_2021.pdf new file mode 100644 index 0000000..0d66045 Binary files /dev/null and b/isabelle/2021/isabelle_exercises_2021.pdf differ