(* tested with Isabelle 2023 *) theory Demo03 imports Main begin (* hide existing constants *) hide_const Nil Cons conj datatype Nat = Zero | Succ Nat thm Nat.simps(1-3) thm Nat.induct[of P y] thm Nat.exhaust[of x P] datatype List = Nil | Cons Nat List thm List.simps(1-3) thm List.induct[of P xs] thm List.exhaust[of xs P] (* Non-emptyness is checked internally, and here the check obviously fails *) datatype Tree = Node Tree Nat Tree function conj :: "bool \ bool \ bool" where "conj True True = True" | "conj False y = False" | "conj x False = False" apply pat_completeness (* first prove pattern completeness *) apply auto (* then show that all overlaps are harmless *) done (* finally prove termination, which is trivial for conj *) termination by lexicographic_order thm conj.simps (* fun does the above manual proof steps internally, and gets rid of overlaps by ordering the equations *) fun conj2 :: "bool \ bool \ bool" where "conj2 True True = True" | "conj2 False y = False" | "conj2 x False = False" thm conj2.simps fun minimum :: "Nat \ Nat \ Nat" where "minimum Zero y = y" | "minimum x Zero = x" | "minimum (Succ x) (Succ y) = Succ (minimum x y)" thm minimum.simps (* fun also resolves underspecification *) fun minlist :: "List \ Nat" where "minlist (Cons x Nil) = x" | "minlist (Cons x xs) = minimum x (minlist xs)" thm minlist.simps end