diff --git a/src/SI/SI_Algebra.thy b/src/SI/SI_Algebra.thy new file mode 100644 index 0000000..69f7007 --- /dev/null +++ b/src/SI/SI_Algebra.thy @@ -0,0 +1,91 @@ +section \ Algebraic Laws \ + +theory SI_Algebra + imports SI_Proof +begin + +subsection \ Quantity Scale \ + +lemma scaleQ_add_right: "a \ x + y = (a \ x) + (a \ y)" + by (transfer, simp add: distrib_left) + +lemma scaleQ_add_left: "a + b \ x = (a \ x) + (b \ x)" + by (transfer, simp add: distrib_right) + +lemma scaleQ_scaleQ: "a \ b \ x = a \ b \ x" + by (transfer, simp add: mult.assoc) + +lemma scaleQ_one [simp]: "1 \ x = x" + by (transfer, simp) + +lemma scaleQ_zero [simp]: "0 \ x = 0" + by (transfer, simp) + +lemma scaleQ_inv: "-a \ x = a \ -x" + by (transfer, simp) + +lemma scaleQ_as_qprod: "a \ x \\<^sub>Q (a \ \) \<^bold>\ x" + unfolding si_def + by (transfer, simp add: si_sem_NoDimension_def) + +lemma mult_scaleQ_left [simp]: "(a \ x) \<^bold>\ y = a \ x \<^bold>\ y" + by (transfer, simp add: si_sem_UnitTimes_def mult.assoc) + +lemma mult_scaleQ_right [simp]: "x \<^bold>\ (a \ y) = a \ x \<^bold>\ y" + by (transfer, simp add: si_sem_UnitTimes_def times_Quantity_ext_def mult.assoc) + +subsection \ Field Laws \ + +lemma qtimes_commute: "x \<^bold>\ y \\<^sub>Q y \<^bold>\ x" + by si_calc + +text\Observe that this commutation law also commutes the types.\ + +(* just a check that instantiation works for special cases ... *) +lemma " (UNIT(x, J) \<^bold>\ UNIT(y::'a::comm_ring_1, N)) + \\<^sub>Q (UNIT(y, N) \<^bold>\ UNIT(x, J)) " + by(simp add: qtimes_commute) + +lemma qtimes_assoc: "(x \<^bold>\ y) \<^bold>\ z \\<^sub>Q x \<^bold>\ (y \<^bold>\ z)" + by (si_calc) + +lemma qtimes_left_unit: "\ \<^bold>\ x \\<^sub>Q x" + by (si_calc) + +lemma qtimes_right_unit: "x \<^bold>\ \ \\<^sub>Q x" + by (si_calc) + +text\The following weak congruences will allow for replacing equivalences in contexts + built from product and inverse. \ + +lemma qtimes_weak_cong_left: + assumes "x \\<^sub>Q y" + shows "x\<^bold>\z \\<^sub>Q y\<^bold>\z" + using assms by si_calc + +lemma qtimes_weak_cong_right: + assumes "x \\<^sub>Q y" + shows "z\<^bold>\x \\<^sub>Q z\<^bold>\y" + using assms by si_calc + +lemma qinverse_weak_cong: + assumes "x \\<^sub>Q y" + shows "x\<^sup>-\<^sup>\ \\<^sub>Q y\<^sup>-\<^sup>\" + using assms by si_calc + +lemma qinverse_qinverse: "x\<^sup>-\<^sup>\\<^sup>-\<^sup>\ \\<^sub>Q x" + by si_calc + +lemma qinverse_nonzero_iff_nonzero: "x\<^sup>-\<^sup>\ = 0 \ x = 0" + by si_calc + +lemma qinverse_qtimes: "(x \<^bold>\ y)\<^sup>-\<^sup>\ \\<^sub>Q x\<^sup>-\<^sup>\ \<^bold>\ y\<^sup>-\<^sup>\" + by si_calc + +lemma qinverse_qdivide: "(x \<^bold>/ y)\<^sup>-\<^sup>\ \\<^sub>Q y \<^bold>/ x" + by si_calc + +lemma qtimes_cancel: "x \ 0 \ x \<^bold>/ x \\<^sub>Q \" + by si_calc + +end diff --git a/src/SI/SI_Constants.thy b/src/SI/SI_Constants.thy index 8080420..b651630 100644 --- a/src/SI/SI_Constants.thy +++ b/src/SI/SI_Constants.thy @@ -23,42 +23,50 @@ text \ The most general types we support must form a field into which the default_sort field_char_0 -abbreviation (input) caesium_frequency:: "'a[T\<^sup>-\<^sup>1]" ("\v\<^sub>C\<^sub>s") where +text \ Hyperfine transition frequency of frequency of Cs \ + +abbreviation caesium_frequency:: "'a[T\<^sup>-\<^sup>1]" ("\v\<^sub>C\<^sub>s") where "caesium_frequency \ 9192631770 \ hertz" -abbreviation speed_of_light :: "'a[L \ T\<^sup>-\<^sup>1]" where +text \ Speed of light in vacuum \ + +abbreviation speed_of_light :: "'a[L \ T\<^sup>-\<^sup>1]" ("\<^bold>c") where "speed_of_light \ 299792458 \ (meter\<^bold>\second\<^sup>-\<^sup>\)" -abbreviation Planck :: "'a[M \ L\<^sup>2 \ T\<^sup>-\<^sup>2 \ T]" where +text \ Planck constant \ + +abbreviation Planck :: "'a[M \ L\<^sup>2 \ T\<^sup>-\<^sup>2 \ T]" ("\<^bold>h") where "Planck \ (6.62607015 \ 1/(10^34)) \ (joule\<^bold>\second)" -abbreviation elementary_charge :: "'a[I \ T]" where +text \ Elementary charge \ + +abbreviation elementary_charge :: "'a[I \ T]" ("\<^bold>e") where "elementary_charge \ (1.602176634 \ 1/(10^19)) \ coulomb" -abbreviation Boltzmann :: "'a[M \ L\<^sup>2 \ T\<^sup>-\<^sup>2 \ \\<^sup>-\<^sup>1]" where +abbreviation Boltzmann :: "'a[M \ L\<^sup>2 \ T\<^sup>-\<^sup>2 \ \\<^sup>-\<^sup>1]" ("\<^bold>k") where "Boltzmann \ (1.380649\1/(10^23)) \ (joule \<^bold>/ kelvin)" -abbreviation Avogadro :: "'a[N\<^sup>-\<^sup>1]" where +abbreviation Avogadro :: "'a[N\<^sup>-\<^sup>1]" ("N\<^sub>A") where "Avogadro \ 6.02214076\(10^23) \ (mole\<^sup>-\<^sup>\)" abbreviation max_luminous_frequency :: "'a[T\<^sup>-\<^sup>1]" where "max_luminous_frequency \ (540\10^12) \ hertz" -abbreviation luminous_efficacy :: "'a[J \ (L\<^sup>2 \ L\<^sup>-\<^sup>2) \ (M \ L\<^sup>2 \ T\<^sup>-\<^sup>3)\<^sup>-\<^sup>1]" where +abbreviation luminous_efficacy :: "'a[J \ (L\<^sup>2 \ L\<^sup>-\<^sup>2) \ (M \ L\<^sup>2 \ T\<^sup>-\<^sup>3)\<^sup>-\<^sup>1]" ("K\<^sub>c\<^sub>d") where "luminous_efficacy \ 683 \ (lumen\<^bold>/watt)" +theorem second_definition: + "1 \ second \\<^sub>Q (9192631770 \ \) \<^bold>/ \v\<^sub>C\<^sub>s" + by si_calc + +theorem meter_definition: + "1 \ meter \\<^sub>Q (\<^bold>c \<^bold>/ (299792458 \ \))\<^bold>\second" + "1 \ meter \\<^sub>Q (9192631770 / 299792458) \ (\<^bold>c \<^bold>/ \v\<^sub>C\<^sub>s)" + by si_calc+ + abbreviation gravitational_constant :: "'a[L\<^sup>3 \ M\<^sup>-\<^sup>1 \ T\<^sup>-\<^sup>2]" where "gravitational_constant \ (6.6743015 \ 1/(10 ^ 11)) \ (meter\<^sup>\\<^bold>\kilogram\<^sup>-\<^sup>\\<^bold>\second\<^sup>-\<^sup>\)" -thm si_def - -theorem Quant_eq_iff_same_dim: - "x \\<^sub>Q y \ x = y" - by (transfer, simp) - -theorem second_definition: "1 \ second \\<^sub>Q (9192631770 \ \) \<^bold>/ \v\<^sub>C\<^sub>s" - by (simp add: unit_equiv_iff, simp add: Quant_equiv_def unit_eq_iff_magn_eq si_def) - default_sort type end \ No newline at end of file diff --git a/src/SI/SI_Derived.thy b/src/SI/SI_Derived.thy index b7664d5..0b27cbd 100644 --- a/src/SI/SI_Derived.thy +++ b/src/SI/SI_Derived.thy @@ -4,22 +4,24 @@ theory SI_Derived imports SI_Prefix begin -definition degree :: "'a::{inverse,real_algebra_1}[L/L]" where +subsection \ Definitions \ + +definition degree :: "'a::real_field[L/L]" where [si_def]: "degree = (2\(of_real pi) / 180) \ radian" abbreviation degrees ("_\" [999] 999) where "n\ \ n \ degree" -definition degrees_celcius :: "'a::division_ring \ 'a[\]" ("_\C" [999] 999) +definition degrees_celcius :: "'a::field \ 'a[\]" ("_\C" [999] 999) where [si_def]: "degrees_celcius x = x + 273.151 \ kelvin" -definition degrees_farenheit :: "'a::division_ring \ 'a[\]" ("_\F" [999] 999) +definition degrees_farenheit :: "'a::field \ 'a[\]" ("_\F" [999] 999) where [si_def]: "degrees_farenheit x = (x + 459.67)\5/9 \ kelvin" definition [si_def]: "litre = 1/1000 \ meter\<^sup>\" definition [si_def]: "pint = 0.56826125 \ litre" -definition [si_def]: "hour = 3600 \ second" +definition [si_def, si_eq]: "hour = 3600 \ second" definition [si_def]: "gram = milli \ kilogram" @@ -39,4 +41,9 @@ text\The full beauty of the approach is perhaps revealed here, with the type of a classical three-dimensional gravitation field:\ type_synonym gravitation_field = "(real\<^sup>3 \ real\<^sup>3)[L \ T\<^sup>-\<^sup>2]" +subsection \ Examples \ + +lemma "watt \<^bold>\ hour \\<^sub>Q 3600 \ joule" + by (si_calc) + end \ No newline at end of file diff --git a/src/SI/SI_Proof.thy b/src/SI/SI_Proof.thy index 570c437..c1c4360 100644 --- a/src/SI/SI_Proof.thy +++ b/src/SI/SI_Proof.thy @@ -1,8 +1,69 @@ +section \ Tactic Support for SI type expressions. \ + theory SI_Proof imports SI_Quantities begin -section \ Tactic Support for SI type expressions. \ +definition magnQuant :: "'a['u::si_type] \ 'a" ("\_\\<^sub>Q") where +[si_def]: "magnQuant x = magn (fromUnit x)" + +lemma unit_eq_iff_magn_eq: + "x = y \ \x\\<^sub>Q = \y\\<^sub>Q" + by (auto simp add: magnQuant_def, transfer, simp) + +lemma unit_equiv_iff: + fixes x :: "'a['u\<^sub>1::si_type]" and y :: "'a['u\<^sub>2::si_type]" + shows "x \\<^sub>Q y \ \x\\<^sub>Q = \y\\<^sub>Q \ SI('u\<^sub>1) = SI('u\<^sub>2)" +proof - + have "\t ta. (ta::'a['u\<^sub>2]) = t \ magn (fromUnit ta) \ magn (fromUnit t)" + by (simp add: magnQuant_def unit_eq_iff_magn_eq) + then show ?thesis + by (metis (full_types) qequiv.rep_eq coerceQuant_eq_iff2 eq_ magnQuant_def) +qed + +lemma unit_le_iff_magn_le: + "x \ y \ \x\\<^sub>Q \ \y\\<^sub>Q" + by (auto simp add: magnQuant_def; (transfer, simp)) + +lemma magnQuant_zero [si_eq]: "\0\\<^sub>Q = 0" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_one [si_eq]: "\1\\<^sub>Q = 1" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_plus [si_eq]: "\x + y\\<^sub>Q = \x\\<^sub>Q + \y\\<^sub>Q" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_scaleQ [si_eq]: "\x *\<^sub>Q y\\<^sub>Q = x * \y\\<^sub>Q" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_qtimes [si_eq]: "\x \<^bold>\ y\\<^sub>Q = \x\\<^sub>Q \ \y\\<^sub>Q" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_qinverse [si_eq]: "\x\<^sup>-\<^sup>\\\<^sub>Q = inverse \x\\<^sub>Q" + by (simp add: magnQuant_def, transfer, simp) + +lemma magnQuant_qdivivide [si_eq]: "\(x::('a::field)[_]) \<^bold>/ y\\<^sub>Q = \x\\<^sub>Q / \y\\<^sub>Q" + by (simp add: magnQuant_def, transfer, simp add: field_class.field_divide_inverse) + +lemma magnQuant_numeral [si_eq]: "\numeral n\\<^sub>Q = numeral n" + apply (induct n, simp_all add: si_def) + apply (metis magnQuant_def magnQuant_one) + apply (metis magnQuant_def magnQuant_plus numeral_code(2)) + apply (metis magnQuant_def magnQuant_one magnQuant_plus numeral_code(3)) + done + +lemma magnQuant_mk [si_eq]: "\UNIT(n, 'u::si_type)\\<^sub>Q = n" + by (simp add: magnQuant_def, transfer, simp) + +method si_calc uses simps = + (simp add: unit_equiv_iff unit_eq_iff_magn_eq unit_le_iff_magn_le si_eq simps) + +lemmas [si_eq] = si_sem_Length_def si_sem_Mass_def si_sem_Time_def + si_sem_Current_def si_sem_Temperature_def si_sem_Amount_def + si_sem_Intensity_def si_sem_NoDimension_def + si_sem_UnitTimes_def si_sem_UnitInv_def + inverse_Unit_ext_def times_Unit_ext_def one_Unit_ext_def lemmas [si_def] = si_sem_Length_def si_sem_Mass_def si_sem_Time_def si_sem_Current_def si_sem_Temperature_def si_sem_Amount_def @@ -23,139 +84,4 @@ lemma "SI(\) = 1" by(simp add: si_def) lemma "SI(N \ \ \ N) = SI(\ \ N\<^sup>2)" by(simp add: si_def) -lemma [si_def]:"fromUnit UNIT(x::'a::one, Time) = - \magn = x, - unit = \Meters = 0, Kilograms = 0, Seconds = 1, Amperes = 0, - Kelvins = 0, Moles = 0, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Time_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Length) = - \magn = x, - unit = \Meters = 1, Kilograms = 0, Seconds = 0, Amperes = 0, - Kelvins = 0, Moles = 0, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Length_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Mass) = - \magn = x, - unit = \Meters = 0, Kilograms = 1, Seconds = 0, Amperes = 0, - Kelvins = 0, Moles = 0, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Mass_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Current) = - \magn = x, - unit = \Meters = 0, Kilograms = 0, Seconds = 0, Amperes = 1, - Kelvins = 0, Moles = 0, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Current_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Temperature) = - \magn = x, - unit = \Meters = 0, Kilograms = 0, Seconds = 0, Amperes = 0, - Kelvins = 1, Moles = 0, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Temperature_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Amount) = - \magn = x, - unit = \Meters = 0, Kilograms = 0, Seconds = 0, Amperes = 0, - Kelvins = 0, Moles = 1, Candelas = 0\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Amount_def) - -lemma [si_def]:"fromUnit UNIT(x::'a::one, Intensity) = - \magn = x, - unit = \Meters = 0, Kilograms = 0, Seconds = 0, Amperes = 0, - Kelvins = 0, Moles = 0, Candelas = 1\\" - by (simp add: mk_unit.rep_eq one_Unit_ext_def si_sem_Intensity_def) - -lemma Unit_times_commute: - fixes X::"'a::{one,ab_semigroup_mult}['b::si_type]"and Y::"'a['c::si_type]" - shows "X \<^bold>\ Y \\<^sub>Q Y \<^bold>\ X" - by (transfer, simp add: mult.commute times_Quantity_ext_def) - -text\Observe that this commutation law also commutes the types.\ - -(* just a check that instantiation works for special cases ... *) -lemma " (UNIT(x, J) \<^bold>\ UNIT(y::'a::{one,ab_semigroup_mult}, N)) - \\<^sub>Q (UNIT(y, N) \<^bold>\ UNIT(x, J)) " - by(simp add: Unit_times_commute) - - -lemma Unit_times_assoc: - fixes X::"'a::{one,ab_semigroup_mult}['b::si_type]" - and Y::"'a['c::si_type]" - and Z::"'a['d::si_type]" - shows "(X \<^bold>\ Y) \<^bold>\ Z \\<^sub>Q X \<^bold>\ (Y \<^bold>\ Z)" - by (transfer, simp add: mult.commute mult.left_commute times_Quantity_ext_def) - -text\The following weak congruences will allow for replacing equivalences in contexts - built from product and inverse. \ -lemma Unit_times_weak_cong_left: - fixes X::"'a::{one,ab_semigroup_mult}['b::si_type]" - and Y::"'a['c::si_type]" - and Z::"'a['d::si_type]" - assumes "X \\<^sub>Q Y" - shows "(X \<^bold>\ Z) \\<^sub>Q (Y \<^bold>\ Z)" - using assms by (transfer, simp) - -lemma Unit_times_weak_cong_right: - fixes X::"'a::{one,ab_semigroup_mult}['b::si_type]" - and Y::"'a['c::si_type]" - and Z::"'a['d::si_type]" - assumes "X \\<^sub>Q Y" - shows "(Z \<^bold>\ X) \\<^sub>Q (Z \<^bold>\ Y)" - using assms by (transfer, simp) - -lemma Unit_inverse_weak_cong: - fixes X::"'a::{field}['b::si_type]" - and Y::"'a['c::si_type]" - assumes "X \\<^sub>Q Y" - shows "(X)\<^sup>-\<^sup>\ \\<^sub>Q (Y)\<^sup>-\<^sup>\" - using assms by (transfer, simp) - -(* -text\In order to compute a normal form, we would additionally need these three:\ -(* field ? *) -lemma Unit_inverse_distrib: - fixes X::"'a::{field}['b::si_type]" - and Y::"'a['c::si_type]" - shows "(X \<^bold>\ Y)\<^sup>-\<^sup>\ \\<^sub>Q X\<^sup>-\<^sup>\ \<^bold>\ Y\<^sup>-\<^sup>\" - apply (transfer) - sorry - -(* field ? *) -lemma Unit_inverse_inverse: - fixes X::"'a::{field}['b::si_type]" - shows "((X)\<^sup>-\<^sup>\)\<^sup>-\<^sup>\ \\<^sub>Q X" - apply transfer - sorry - -(* field ? *) -lemma Unit_mult_cancel: - fixes X::"'a::{field}['b::si_type]" - shows "X \<^bold>/ X \\<^sub>Q 1" - apply transfer - sorry - - -lemma Unit_mult_mult_Left_cancel: - fixes X::"'a::{field}['b::si_type]" - shows "(1::'a['b/'b]) \<^bold>\ X \\<^sub>Q X" - apply transfer - sorry - - -lemma "watt \<^bold>\ hour \\<^sub>Q 3600 \<^bold>\ joule" - unfolding Unit_equiv_def hour_def - apply(simp add: Units.Unit_times.rep_eq si_def - zero_SI_tagged_domain_ext_def times_SI_tagged_domain_ext_def - inverse_SI_tagged_domain_ext_def - Unit_inverse_def Unit_times_def) - find_theorems fromUnit - oops - - thm Units.Unit.toUnit_inverse - - -lemma "watt \<^bold>\ hour \\<^sub>Q 3.6 \<^bold>\ kilo \<^bold>\ joule" - oops -*) - end \ No newline at end of file diff --git a/src/SI/SI_Quantities.thy b/src/SI/SI_Quantities.thy index b8d8036..bf1c9a3 100644 --- a/src/SI/SI_Quantities.thy +++ b/src/SI/SI_Quantities.thy @@ -79,6 +79,20 @@ instance Quantity_ext :: (comm_monoid_mult, comm_monoid_mult) comm_monoid_mult instance Quantity_ext :: (ab_group_mult, ab_group_mult) ab_group_mult by (intro_classes, rule Quantity_eq_intro, simp_all) +instantiation Quantity_ext :: (ord, ord) ord +begin + definition less_eq_Quantity_ext :: "('a, 'b) Quantity_scheme \ ('a, 'b) Quantity_scheme \ bool" + where "less_eq_Quantity_ext x y = (magn x \ magn y \ unit x = unit y \ more x \ more y)" + definition less_Quantity_ext :: "('a, 'b) Quantity_scheme \ ('a, 'b) Quantity_scheme \ bool" + where "less_Quantity_ext x y = (x \ y \ \ y \ x)" + +instance .. + +end + +instance Quantity_ext :: (order, order) order + by (intro_classes, auto simp add: less_Quantity_ext_def less_eq_Quantity_ext_def) + subsection \ SI Tagged Types \ text\We 'lift' SI type expressions to SI tagged type expressions as follows:\ @@ -99,73 +113,81 @@ subsection\Predicates on SI-tagged types\ text \ Two SI types are equivalent if they have the same value-level units. \ -lift_definition Quant_equiv :: "'n['a::si_type] \ 'n['b::si_type] \ bool" (infix "\\<^sub>Q" 50) is +lift_definition qless_eq :: "'n::order['a::si_type] \ 'n['b::si_type] \ bool" (infix "\\<^sub>Q" 50) is +"(\)" . + +lift_definition qequiv :: "'n['a::si_type] \ 'n['b::si_type] \ bool" (infix "\\<^sub>Q" 50) is "(=)" . text\This gives us an equivalence, but, unfortunately, not a congruence.\ -lemma Quant_equiv_refl [simp]: "a \\<^sub>Q a" - by (simp add: Quant_equiv_def) +lemma qequiv_refl [simp]: "a \\<^sub>Q a" + by (simp add: qequiv_def) -lemma Quant_equiv_sym: "a \\<^sub>Q b \ b \\<^sub>Q a" - by (simp add: Quant_equiv_def) +lemma qequiv_sym: "a \\<^sub>Q b \ b \\<^sub>Q a" + by (simp add: qequiv_def) -lemma Quant_equiv_trans: "\ a \\<^sub>Q b; b \\<^sub>Q c \ \ a \\<^sub>Q c" - by (simp add: Quant_equiv_def) +lemma qequiv_trans: "\ a \\<^sub>Q b; b \\<^sub>Q c \ \ a \\<^sub>Q c" + by (simp add: qequiv_def) + +theorem qeq_iff_same_dim: + fixes x y :: "'a['u::si_type]" + shows "x \\<^sub>Q y \ x = y" + by (transfer, simp) (* the following series of equivalent statements ... *) lemma coerceQuant_eq_iff: fixes x :: "'a['u\<^sub>1::si_type]" assumes "SI('u\<^sub>1) = SI('u\<^sub>2::si_type)" - shows "(coerceUnit TYPE('u\<^sub>2) x) \\<^sub>Q x" - by (metis Quant_equiv.rep_eq assms coerceUnit_def toUnit_cases toUnit_inverse) + shows "(coerceUnit TYPE('u\<^sub>2) x) \\<^sub>Q x" + by (metis qequiv.rep_eq assms coerceUnit_def toUnit_cases toUnit_inverse) (* or equivalently *) lemma coerceQuant_eq_iff2: fixes x :: "'a['u\<^sub>1::si_type]" assumes "SI('u\<^sub>1) = SI('u\<^sub>2::si_type)" and "y = (coerceUnit TYPE('u\<^sub>2) x)" - shows "x \\<^sub>Q y" - using Quant_equiv_sym assms(1) assms(2) coerceQuant_eq_iff by blast + shows "x \\<^sub>Q y" + using qequiv_sym assms(1) assms(2) coerceQuant_eq_iff by blast lemma updown_eq_iff: fixes x :: "'a['u\<^sub>1::si_type]" fixes y :: "'a['u\<^sub>2::si_type]" assumes "SI('u\<^sub>1) = SI('u\<^sub>2::si_type)" and "y = (toUnit (fromUnit x))" - shows "x \\<^sub>Q y" + shows "x \\<^sub>Q y" by (simp add: assms(1) assms(2) coerceQuant_eq_iff2 coerceUnit_def) -text\This is more general that \y = x \ x \\<^sub>Q y\, since x and y may have different type.\ +text\This is more general that \y = x \ x \\<^sub>Q y\, since x and y may have different type.\ find_theorems "(toUnit (fromUnit _))" lemma eq_ : fixes x :: "'a['u\<^sub>1::si_type]" fixes y :: "'a['u\<^sub>2::si_type]" - assumes "x \\<^sub>Q y" + assumes "x \\<^sub>Q y" shows "SI('u\<^sub>1) = SI('u\<^sub>2::si_type)" - by (metis (full_types) Quant_equiv.rep_eq assms fromUnit mem_Collect_eq) + by (metis (full_types) qequiv.rep_eq assms fromUnit mem_Collect_eq) subsection\Operations on SI-tagged types\ lift_definition - Quant_times :: "('n::times)['a::si_type] \ 'n['b::si_type] \ 'n['a \'b]" (infixl "\<^bold>\" 69) is "(*)" + qtimes :: "('n::comm_ring_1)['a::si_type] \ 'n['b::si_type] \ 'n['a \'b]" (infixl "\<^bold>\" 69) is "(*)" by (simp add: si_sem_UnitTimes_def times_Quantity_ext_def) lift_definition - Quant_inverse :: "('n::inverse)['a::si_type] \ 'n['a\<^sup>-\<^sup>1]" ("(_\<^sup>-\<^sup>\)" [999] 999) is "inverse" + qinverse :: "('n::field)['a::si_type] \ 'n['a\<^sup>-\<^sup>1]" ("(_\<^sup>-\<^sup>\)" [999] 999) is "inverse" by (simp add: inverse_Quantity_ext_def si_sem_UnitInv_def) abbreviation - Quant_divide :: "('n::{times,inverse})['a::si_type] \ 'n['b::si_type] \ 'n['a/'b]" (infixl "\<^bold>'/" 70) where -"Quant_divide x y \ x \<^bold>\ y\<^sup>-\<^sup>\" + qdivide :: "('n::field)['a::si_type] \ 'n['b::si_type] \ 'n['a/'b]" (infixl "\<^bold>'/" 70) where +"qdivide x y \ x \<^bold>\ y\<^sup>-\<^sup>\" -abbreviation Quant_sq ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u" -abbreviation Quant_cube ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u\<^bold>\u" -abbreviation Quant_quart ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u\<^bold>\u\<^bold>\u" +abbreviation qsq ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u" +abbreviation qcube ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u\<^bold>\u" +abbreviation qquart ("(_)\<^sup>\" [999] 999) where "u\<^sup>\ \ u\<^bold>\u\<^bold>\u\<^bold>\u" -abbreviation Quant_neq_sq ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" -abbreviation Quant_neq_cube ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" -abbreviation Quant_neq_quart ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" +abbreviation qneq_sq ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" +abbreviation qneq_cube ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" +abbreviation qneq_quart ("(_)\<^sup>-\<^sup>\" [999] 999) where "u\<^sup>-\<^sup>\ \ (u\<^sup>\)\<^sup>-\<^sup>\" instantiation tQuant :: (zero,si_type) zero begin @@ -228,7 +250,7 @@ begin instance by (intro_classes, (transfer, simp add: less_le_not_le)+) end -lift_definition scaleQ :: "'a \ 'a::times['u::si_type] \ 'a['u]" (infixr "*\<^sub>Q" 63) +lift_definition scaleQ :: "'a \ 'a::comm_ring_1['u::si_type] \ 'a['u]" (infixr "*\<^sub>Q" 63) is "\ r x. \ magn = r * magn x, unit = SI('u) \" by simp notation scaleQ (infixr "\" 63) @@ -241,70 +263,15 @@ translations "UNIT(n, 'a)" == "CONST mk_unit n TYPE('a)" subsection \Polymorphic Operations for Elementary SI Units \ -definition [si_def]: "meter = UNIT(1, Length)" -definition [si_def]: "second = UNIT(1, Time)" -definition [si_def]: "kilogram = UNIT(1, Mass)" -definition [si_def]: "ampere = UNIT(1, Current)" -definition [si_def]: "kelvin = UNIT(1, Temperature)" -definition [si_def]: "mole = UNIT(1, Amount)" -definition [si_def]: "candela = UNIT(1, Intensity)" +definition [si_def, si_eq]: "meter = UNIT(1, Length)" +definition [si_def, si_eq]: "second = UNIT(1, Time)" +definition [si_def, si_eq]: "kilogram = UNIT(1, Mass)" +definition [si_def, si_eq]: "ampere = UNIT(1, Current)" +definition [si_def, si_eq]: "kelvin = UNIT(1, Temperature)" +definition [si_def, si_eq]: "mole = UNIT(1, Amount)" +definition [si_def, si_eq]: "candela = UNIT(1, Intensity)" definition dimless ("\") - where [si_def]: "dimless = UNIT(1, NoDimension)" - -subsubsection \The Projection: Stripping the SI-Tags \ - -definition magnQuant :: "'a['u::si_type] \ 'a" ("\_\\<^sub>Q") where -"magnQuant x = magn (fromUnit x)" - -subsubsection \More Operations \ - -lemma unit_eq_iff_magn_eq: - "x = y \ \x\\<^sub>Q = \y\\<^sub>Q" - by (auto simp add: magnQuant_def, transfer, simp) - -lemma unit_equiv_iff: - fixes x :: "'a['u\<^sub>1::si_type]" and y :: "'a['u\<^sub>2::si_type]" - shows "x \\<^sub>Q y \ \x\\<^sub>Q = \y\\<^sub>Q \ SI('u\<^sub>1) = SI('u\<^sub>2)" -proof - - have "\t ta. (ta::'a['u\<^sub>2]) = t \ magn (fromUnit ta) \ magn (fromUnit t)" - by (simp add: magnQuant_def unit_eq_iff_magn_eq) - then show ?thesis - by (metis (full_types) Quant_equiv.rep_eq coerceQuant_eq_iff2 eq_ magnQuant_def) -qed - -lemma unit_le_iff_magn_le: - "x \ y \ \x\\<^sub>Q \ \y\\<^sub>Q" - by (auto simp add: magnQuant_def; (transfer, simp)) - -lemma magnQuant_zero [si_def]: "\0\\<^sub>Q = 0" - by (simp add: magnQuant_def, transfer, simp) - -lemma magnQuant_one [si_def]: "\1\\<^sub>Q = 1" - by (simp add: magnQuant_def, transfer, simp) - -lemma magnQuant_plus [si_def]: "\x + y\\<^sub>Q = \x\\<^sub>Q + \y\\<^sub>Q" - by (simp add: magnQuant_def, transfer, simp) - -lemma magnQuant_scaleQ [si_def]: "\x *\<^sub>Q y\\<^sub>Q = x * \y\\<^sub>Q" - by (simp add: magnQuant_def, transfer, simp) - -lemma magnQuant_qinv [si_def]: "\x\<^sup>-\<^sup>\\\<^sub>Q = inverse \x\\<^sub>Q" - by (simp add: magnQuant_def, transfer, simp) - -lemma magnQuant_qdiv [si_def]: "\(x::('a::field)[_]) \<^bold>/ y\\<^sub>Q = \x\\<^sub>Q / \y\\<^sub>Q" - by (simp add: magnQuant_def, transfer, simp add: field_class.field_divide_inverse) - -lemma magnQuant_numeral [si_def]: "\numeral n\\<^sub>Q = numeral n" - apply (induct n, simp_all add: si_def) - apply (metis magnQuant_plus numeral_code(2)) - apply (metis magnQuant_one magnQuant_plus numeral_code(3)) - done - -lemma magnQuant_mk [si_def]: "\UNIT(n, 'u::si_type)\\<^sub>Q = n" - by (simp add: magnQuant_def, transfer, simp) - -method si_calc = - (simp add: unit_eq_iff_magn_eq unit_le_iff_magn_le si_def) + where [si_def, si_eq]: "dimless = UNIT(1, NoDimension)" end \ No newline at end of file diff --git a/src/SI/SI_Units.thy b/src/SI/SI_Units.thy index e899f20..710f1e2 100644 --- a/src/SI/SI_Units.thy +++ b/src/SI/SI_Units.thy @@ -6,7 +6,7 @@ theory SI_Units "HOL-Eisbach.Eisbach" begin -named_theorems si_def +named_theorems si_def and si_eq text\ The International System of Units (SI, abbreviated from the French