20 |
20 |
21 lemma sat_eq_iff: |
21 lemma sat_eq_iff: |
22 "m = n \<longleftrightarrow> nat_of m = nat_of n" |
22 "m = n \<longleftrightarrow> nat_of m = nat_of n" |
23 by (simp add: nat_of_inject) |
23 by (simp add: nat_of_inject) |
24 |
24 |
25 lemma Abs_sa_nat_of [code abstype]: |
25 lemma Abs_sat_nat_of [code abstype]: |
26 "Abs_sat (nat_of n) = n" |
26 "Abs_sat (nat_of n) = n" |
27 by (fact nat_of_inverse) |
27 by (fact nat_of_inverse) |
28 |
28 |
29 definition Sat :: "nat \<Rightarrow> 'a::len sat" where |
29 definition Abs_sat' :: "nat \<Rightarrow> 'a::len sat" where |
30 "Sat n = Abs_sat (min (len_of TYPE('a)) n)" |
30 "Abs_sat' n = Abs_sat (min (len_of TYPE('a)) n)" |
31 |
31 |
32 lemma nat_of_Sat [simp]: |
32 lemma nat_of_Abs_sat' [simp]: |
33 "nat_of (Sat n :: ('a::len) sat) = min (len_of TYPE('a)) n" |
33 "nat_of (Abs_sat' n :: ('a::len) sat) = min (len_of TYPE('a)) n" |
34 unfolding Sat_def by (rule Abs_sat_inverse) simp |
34 unfolding Abs_sat'_def by (rule Abs_sat_inverse) simp |
35 |
35 |
36 lemma nat_of_le_len_of [simp]: |
36 lemma nat_of_le_len_of [simp]: |
37 "nat_of (n :: ('a::len) sat) \<le> len_of TYPE('a)" |
37 "nat_of (n :: ('a::len) sat) \<le> len_of TYPE('a)" |
38 using nat_of [where x = n] by simp |
38 using nat_of [where x = n] by simp |
39 |
39 |
43 |
43 |
44 lemma min_nat_of_len_of [simp]: |
44 lemma min_nat_of_len_of [simp]: |
45 "min (nat_of (n::('a::len) sat)) (len_of TYPE('a)) = nat_of n" |
45 "min (nat_of (n::('a::len) sat)) (len_of TYPE('a)) = nat_of n" |
46 by (subst min_max.inf.commute) simp |
46 by (subst min_max.inf.commute) simp |
47 |
47 |
48 lemma Sat_nat_of [simp]: |
48 lemma Abs_sat'_nat_of [simp]: |
49 "Sat (nat_of n) = n" |
49 "Abs_sat' (nat_of n) = n" |
50 by (simp add: Sat_def nat_of_inverse) |
50 by (simp add: Abs_sat'_def nat_of_inverse) |
51 |
51 |
52 instantiation sat :: (len) linorder |
52 instantiation sat :: (len) linorder |
53 begin |
53 begin |
54 |
54 |
55 definition |
55 definition |
65 |
65 |
66 instantiation sat :: (len) "{minus, comm_semiring_1}" |
66 instantiation sat :: (len) "{minus, comm_semiring_1}" |
67 begin |
67 begin |
68 |
68 |
69 definition |
69 definition |
70 "0 = Sat 0" |
70 "0 = Abs_sat' 0" |
71 |
71 |
72 definition |
72 definition |
73 "1 = Sat 1" |
73 "1 = Abs_sat' 1" |
74 |
74 |
75 lemma nat_of_zero_sat [simp, code abstract]: |
75 lemma nat_of_zero_sat [simp, code abstract]: |
76 "nat_of 0 = 0" |
76 "nat_of 0 = 0" |
77 by (simp add: zero_sat_def) |
77 by (simp add: zero_sat_def) |
78 |
78 |
79 lemma nat_of_one_sat [simp, code abstract]: |
79 lemma nat_of_one_sat [simp, code abstract]: |
80 "nat_of 1 = min 1 (len_of TYPE('a))" |
80 "nat_of 1 = min 1 (len_of TYPE('a))" |
81 by (simp add: one_sat_def) |
81 by (simp add: one_sat_def) |
82 |
82 |
83 definition |
83 definition |
84 "x + y = Sat (nat_of x + nat_of y)" |
84 "x + y = Abs_sat' (nat_of x + nat_of y)" |
85 |
85 |
86 lemma nat_of_plus_sat [simp, code abstract]: |
86 lemma nat_of_plus_sat [simp, code abstract]: |
87 "nat_of (x + y) = min (nat_of x + nat_of y) (len_of TYPE('a))" |
87 "nat_of (x + y) = min (nat_of x + nat_of y) (len_of TYPE('a))" |
88 by (simp add: plus_sat_def) |
88 by (simp add: plus_sat_def) |
89 |
89 |
90 definition |
90 definition |
91 "x - y = Sat (nat_of x - nat_of y)" |
91 "x - y = Abs_sat' (nat_of x - nat_of y)" |
92 |
92 |
93 lemma nat_of_minus_sat [simp, code abstract]: |
93 lemma nat_of_minus_sat [simp, code abstract]: |
94 "nat_of (x - y) = nat_of x - nat_of y" |
94 "nat_of (x - y) = nat_of x - nat_of y" |
95 proof - |
95 proof - |
96 from nat_of_le_len_of [of x] have "nat_of x - nat_of y \<le> len_of TYPE('a)" by arith |
96 from nat_of_le_len_of [of x] have "nat_of x - nat_of y \<le> len_of TYPE('a)" by arith |
97 then show ?thesis by (simp add: minus_sat_def) |
97 then show ?thesis by (simp add: minus_sat_def) |
98 qed |
98 qed |
99 |
99 |
100 definition |
100 definition |
101 "x * y = Sat (nat_of x * nat_of y)" |
101 "x * y = Abs_sat' (nat_of x * nat_of y)" |
102 |
102 |
103 lemma nat_of_times_sat [simp, code abstract]: |
103 lemma nat_of_times_sat [simp, code abstract]: |
104 "nat_of (x * y) = min (nat_of x * nat_of y) (len_of TYPE('a))" |
104 "nat_of (x * y) = min (nat_of x * nat_of y) (len_of TYPE('a))" |
105 by (simp add: times_sat_def) |
105 by (simp add: times_sat_def) |
106 |
106 |
143 instance |
143 instance |
144 by default (auto simp add: less_eq_sat_def less_sat_def not_le sat_eq_iff min_max.le_infI1 nat_mult_commute) |
144 by default (auto simp add: less_eq_sat_def less_sat_def not_le sat_eq_iff min_max.le_infI1 nat_mult_commute) |
145 |
145 |
146 end |
146 end |
147 |
147 |
148 lemma Sat_eq_of_nat: "Sat n = of_nat n" |
148 lemma Abs_sat'_eq_of_nat: "Abs_sat' n = of_nat n" |
149 by (rule sat_eqI, induct n, simp_all) |
149 by (rule sat_eqI, induct n, simp_all) |
150 |
150 |
|
151 abbreviation Sat :: "nat \<Rightarrow> 'a::len sat" where |
|
152 "Sat \<equiv> of_nat" |
|
153 |
|
154 lemma nat_of_Sat [simp]: |
|
155 "nat_of (Sat n :: ('a::len) sat) = min (len_of TYPE('a)) n" |
|
156 by (rule nat_of_Abs_sat' [unfolded Abs_sat'_eq_of_nat]) |
|
157 |
151 instantiation sat :: (len) number_semiring |
158 instantiation sat :: (len) number_semiring |
152 begin |
159 begin |
153 |
160 |
154 definition |
161 definition |
155 number_of_sat_def [code del]: "number_of = Sat \<circ> nat" |
162 number_of_sat_def [code del]: "number_of = Sat \<circ> nat" |
156 |
163 |
157 instance |
164 instance |
158 by default (simp add: number_of_sat_def Sat_eq_of_nat) |
165 by default (simp add: number_of_sat_def) |
159 |
166 |
160 end |
167 end |
161 |
168 |
162 lemma [code abstract]: |
169 lemma [code abstract]: |
163 "nat_of (number_of n :: ('a::len) sat) = min (nat n) (len_of TYPE('a))" |
170 "nat_of (number_of n :: ('a::len) sat) = min (nat n) (len_of TYPE('a))" |