theory HSV_chapter5 imports Main begin section \Representing circuits (cf. worksheet Section 5.1)\ text \Defining a data structure to represent fan-out-free circuits with numbered inputs\ datatype "circuit" = NOT "circuit" | AND "circuit" "circuit" | OR "circuit" "circuit" | TRUE | FALSE | INPUT "int" text \A few example circuits\ definition "circuit1 == AND (INPUT 1) (INPUT 2)" definition "circuit2 == OR (NOT circuit1) FALSE" definition "circuit3 == NOT (NOT circuit2)" definition "circuit4 == AND circuit3 (INPUT 3)" section \Simulating circuits (cf. worksheet Section 5.2)\ text \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" text \A few example valuations\ definition "\0 == \_. True" definition "\1 == \0(1 := True, 2 := False, 3 := True)" definition "\2 == \0(1 := True, 2 := True, 3 := True)" text \Trying out the simulator\ value "simulate circuit1 \1" value "simulate circuit2 \1" value "simulate circuit3 \1" value "simulate circuit4 \1" value "simulate circuit1 \2" value "simulate circuit2 \2" value "simulate circuit3 \2" value "simulate circuit4 \2" section \Structural induction on circuits (cf. worksheet Section 5.3)\ text \A function that switches each pair of wires entering an OR or AND gate\ fun mirror where "mirror (NOT c) = NOT (mirror c)" | "mirror (AND c1 c2) = AND (mirror c2) (mirror c1)" | "mirror (OR c1 c2) = OR (mirror c2) (mirror c1)" | "mirror TRUE = TRUE" | "mirror FALSE = FALSE" | "mirror (INPUT i) = INPUT i" value "circuit1" value "mirror circuit1" value "circuit2" value "mirror circuit2" text \The following non-theorem is easily contradicted.\ theorem "mirror c = c" oops text \Proving that mirroring doesn't affect simulation behaviour.\ theorem mirror_is_sound: "simulate (mirror c) \ = simulate c \" by (induct c, auto) section \A simple circuit optimiser (cf. worksheet Section 5.4)\ text \A function that optimises a circuit by removing pairs of consecutive NOT gates\ fun opt_NOT where "opt_NOT (NOT (NOT c)) = opt_NOT c" | "opt_NOT (NOT c) = NOT (opt_NOT c)" | "opt_NOT (AND c1 c2) = AND (opt_NOT c1) (opt_NOT c2)" | "opt_NOT (OR c1 c2) = OR (opt_NOT c1) (opt_NOT c2)" | "opt_NOT TRUE = TRUE" | "opt_NOT FALSE = FALSE" | "opt_NOT (INPUT i) = INPUT i" text \Trying out the optimiser\ value "circuit1" value "opt_NOT circuit1" value "circuit2" value "opt_NOT circuit2" value "circuit3" value "opt_NOT circuit3" value "circuit4" value "opt_NOT circuit4" section \Rule induction (cf. worksheet Section 5.5)\ text \A Fibonacci function that demonstrates complex recursion schemes\ fun f :: "nat \ nat" where "f (Suc (Suc n)) = f n + f (Suc n)" | "f (Suc 0) = 1" | "f 0 = 1" thm f.induct (* rule induction theorem for f *) text \We need to prove a stronger version of the theorem below first, in order to make the inductive step work. Just like how it often goes with loop invariants in Dafny!\ lemma helper: "f n \ n \ f n \ 1" by (rule f.induct[of "\n. f n \ n \ f n \ 1"], auto) text \The nth Fibonacci number is greater than or equal to n\ theorem "f n \ n" using helper by simp section \Verifying our optimiser (cf. worksheet Section 5.6)\ text \The following non-theorem is easily contradicted.\ theorem "opt_NOT c = c" oops text \The following theorem says that the optimiser is sound.\ theorem opt_NOT_is_sound: "simulate (opt_NOT c) \ = simulate c \" by (induct rule:opt_NOT.induct, auto) end