(* Author: Carsten Schuermann *) (* Circuits *) signature CIRCUIT = sig datatype Gate = BIND of Gate * (Gate -> Gate) | NOT of Gate | NAND of Gate * Gate | NOR of Gate * Gate | SIGNAL of bool val simulate : Gate -> bool end structure Circuit : CIRCUIT = struct datatype Gate = BIND of Gate * (Gate -> Gate) | NOT of Gate | NAND of Gate * Gate | NOR of Gate * Gate | SIGNAL of bool fun simulate (BIND (C, C')) = simulate (C' (SIGNAL (simulate C))) | simulate (NOT C) = not (simulate C) | simulate (NAND (C1, C2)) = not (simulate C1 andalso simulate C2) | simulate (NOR (C1, C2)) = not (simulate C1 orelse simulate C2) | simulate (SIGNAL B) = B end (* a---|----| |NAND|- c --|----| b-x-|----| |NAND|--- d | | | --------------|----| *) local open Circuit in fun circuit a b = BIND (NAND (a, b), fn c => NAND (c, b)) val c1 = simulate (circuit (SIGNAL true) (SIGNAL false)) fun tester3 f = let fun tester3' 0 [a, b, c] = f (a, b, c) | tester3' n L = (tester3' (n-1) (true :: L); tester3' (n-1) (false :: L)) in tester3' 3 [] end fun boolToString true = " T " | boolToString false = " - " fun entryToString (a,b,c) d = (boolToString a ^ boolToString b ^ boolToString c ^ " | " ^ boolToString d ^ "\n") fun ifthenelse (a, b, c) = NAND (NAND(a, b), NAND (NAND (a, a), c)) val _ = tester3 (fn (a, b, c) => print (entryToString (a, b, c) (simulate (ifthenelse (SIGNAL a, SIGNAL b, SIGNAL c))))) end