theory Numeral imports Main begin typedef num = \{n::nat. n > 0}\ morphisms nat_of_num Num by auto setup_lifting type_definition_num lift_definition One :: num is \Suc 0\ by simp lift_definition Bit0 :: \num \ num\ is \\n. Suc (Suc 0) * n\ by simp lift_definition Bit1 :: \num \ num\ is \\n. Suc (Suc (Suc 0) * n)\ by simp free_constructors case_num for One | Bit0 | Bit1 proof - fix m n :: num show \Bit0 n = Bit0 m \ n = m\ by transfer auto show \Bit1 n = Bit1 m \ n = m\ by transfer auto show \One \ Bit0 n\ by transfer auto show \One \ Bit1 n\ by transfer auto show \Bit0 m \ Bit1 n\ by transfer arith show P if \n = One \ P\ \\m. n = Bit0 m \ P\ \\m. n = Bit1 m \ P\ for P using that proof (transfer fixing: P) fix n :: nat assume \n > 0\ and One: \n = Suc 0 \ P\ and Bit0: \\m. 0 < m \ n = Suc (Suc 0) * m \ P\ and Bit1: \\m. 0 < m \ n = Suc (Suc (Suc 0) * m) \ P\ consider \n = Suc 0\ | \even n\ | \n > 2 \ odd n\ by (cases \even n\; cases \n = Suc 0\) (auto elim: oddE) then show P proof cases case 1 with One show P by simp next case 2 with \n > 0\ Bit0 [of \n div 2\] show P by (simp flip: numeral_2_eq_2) next case 3 with Bit1 [of \n div 2\] show P by (simp flip: numeral_2_eq_2) qed qed qed context includes lifting_syntax begin lemma num_induct [case_names One Bit0 Bit1, induct type: num]: \P n\ if One: \P One\ and Bit0: \\n. P n \ P (Bit0 n)\ and Bit1: \\n. P n \ P (Bit1 n)\ proof - define Q where \Q n = P (Num n)\ for n have [transfer_rule]: \(pcr_num ===> (\)) Q P\ proof fix m and n assume \pcr_num n m\ then have \n = nat_of_num m\ by (auto simp add: pcr_num_def cr_num_def) then show \Q n \ P m\ by (simp add: Q_def nat_of_num_inverse) qed show ?thesis proof transfer fix n :: nat assume \n > 0\ moreover from One have \Q (Suc 0)\ by transfer moreover from Bit0 have \\n. n > 0 \ Q n \ Q (Suc (Suc 0) * n)\ by transfer moreover from Bit1 have \\n. n > 0 \ Q n \ Q (Suc (Suc (Suc 0) * n))\ by transfer ultimately show \Q n\ proof (induction n rule: nat_bit_induct) case zero then show ?case by simp next case (even n) then show ?case by (simp add: mult_2) next case (odd n) then show ?case by (cases \n = 0\) (simp_all add: mult_2) qed qed qed end primrec inc :: \num \ num\ where \inc One = Bit0 One\ | \inc (Bit0 x) = Bit1 x\ | \inc (Bit1 x) = Bit0 (inc x)\ end