VQCS.Nunit
Zero dimensions, means a pure number value.
Equality Decidable of Dims
Ltac des_dims1 d1 :=
destruct d1 as [[[[[[?a ?a] ?a] ?a] ?a] ?a] ?a].
Ltac des_dims2 d1 d2 :=
destruct d1 as [[[[[[?a ?a] ?a] ?a] ?a] ?a] ?a];
destruct d2 as [[[[[[?b ?b] ?b] ?b] ?b] ?b] ?b].
Ltac des_dims3 d1 d2 d3 :=
destruct d1 as [[[[[[?a ?a] ?a] ?a] ?a] ?a] ?a];
destruct d2 as [[[[[[?b ?b] ?b] ?b] ?b] ?b] ?b];
destruct d3 as [[[[[[?c ?c] ?c] ?c] ?c] ?c] ?c].
Equality of Dims is decidable.
Lemma deq_dec : forall (d1 d2 : Dims), {d1 = d2} + {d1 <> d2}.
Proof.
intros. des_dims2 d1 d2. eapply pair_dec7.
Unshelve. all: apply Z.eq_dec.
Defined.
Proof.
intros. des_dims2 d1 d2. eapply pair_dec7.
Unshelve. all: apply Z.eq_dec.
Defined.
Equality of Dims, iff all components are equal.
Lemma deq_iff : forall (d1 d2 : Dims),
let '(a,a0,a1,a2,a3,a4,a5) := d1 in
let '(b,b0,b1,b2,b3,b4,b5) := d2 in
d1 = d2 <-> a = b /\ a0 = b0 /\ a1 = b1 /\ a2 = b2 /\ a3 = b3 /\ a4 = b4 /\ a5 = b5.
Proof. intros. des_dims2 d1 d2. apply pair_eq7. Qed.
let '(a,a0,a1,a2,a3,a4,a5) := d1 in
let '(b,b0,b1,b2,b3,b4,b5) := d2 in
d1 = d2 <-> a = b /\ a0 = b0 /\ a1 = b1 /\ a2 = b2 /\ a3 = b3 /\ a4 = b4 /\ a5 = b5.
Proof. intros. des_dims2 d1 d2. apply pair_eq7. Qed.
Inequality of Dims, iff at least one of the dimension is not equal.
Lemma dneq_iff : forall (d1 d2 : Dims),
let '(a,a0,a1,a2,a3,a4,a5) := d1 in
let '(b,b0,b1,b2,b3,b4,b5) := d2 in
d1 <> d2 <-> a <> b \/ a0 <> b0 \/ a1 <> b1 \/ a2 <> b2 \/ a3 <> b3 \/ a4 <> b4 \/ a5 <> b5.
Proof. intros. des_dims2 d1 d2. apply pair_neq7. Qed.
let '(a,a0,a1,a2,a3,a4,a5) := d1 in
let '(b,b0,b1,b2,b3,b4,b5) := d2 in
d1 <> d2 <-> a <> b \/ a0 <> b0 \/ a1 <> b1 \/ a2 <> b2 \/ a3 <> b3 \/ a4 <> b4 \/ a5 <> b5.
Proof. intros. des_dims2 d1 d2. apply pair_neq7. Qed.
Definition deqb (d1 d2 : Dims) : bool.
des_dims2 d1 d2.
exact (
Z.eqb a b &&
Z.eqb a0 b0 &&
Z.eqb a1 b1 &&
Z.eqb a2 b2 &&
Z.eqb a3 b3 &&
Z.eqb a4 b4 &&
Z.eqb a5 b5).
Defined.
des_dims2 d1 d2.
exact (
Z.eqb a b &&
Z.eqb a0 b0 &&
Z.eqb a1 b1 &&
Z.eqb a2 b2 &&
Z.eqb a3 b3 &&
Z.eqb a4 b4 &&
Z.eqb a5 b5).
Defined.
deqb is true, iff propositonal equal.
Lemma deqb_true_iff (d1 d2 : Dims) : deqb d1 d2 = true <-> d1 = d2.
Proof.
pose proof (deq_iff d1 d2). des_dims2 d1 d2. rewrite H. simpl.
rewrite <- !Z.eqb_eq. rewrite !andb_true_iff. tauto.
Qed.
Proof.
pose proof (deq_iff d1 d2). des_dims2 d1 d2. rewrite H. simpl.
rewrite <- !Z.eqb_eq. rewrite !andb_true_iff. tauto.
Qed.
deqb is false, iff propositonal not equal.
Lemma deqb_false_iff (d1 d2 : Dims) :
deqb d1 d2 = false <-> d1 <> d2.
Proof. intros. rewrite <- deqb_true_iff. autoBool. Qed.
Lemma deqb_reflect : forall d1 d2 : Dims, reflect (d1 = d2) (deqb d1 d2).
Proof.
intros. destruct (deqb d1 d2) eqn:E1; constructor.
apply deqb_true_iff; auto. apply deqb_false_iff; auto.
Qed.
Hint Resolve deqb_reflect : bdestruct.
deqb d1 d2 = false <-> d1 <> d2.
Proof. intros. rewrite <- deqb_true_iff. autoBool. Qed.
Lemma deqb_reflect : forall d1 d2 : Dims, reflect (d1 = d2) (deqb d1 d2).
Proof.
intros. destruct (deqb d1 d2) eqn:E1; constructor.
apply deqb_true_iff; auto. apply deqb_false_iff; auto.
Qed.
Hint Resolve deqb_reflect : bdestruct.
deqb is reflexive.
deqb is commutative.
Lemma deqb_comm d1 d2 : deqb d1 d2 = deqb d2 d1.
Proof. bdestruct (deqb d1 d2); bdestruct (deqb d2 d1); auto. congruence. Qed.
Proof. bdestruct (deqb d1 d2); bdestruct (deqb d2 d1); auto. congruence. Qed.
Definition dmakeByBU (b : BaseUnit) (z : Z) : Dims :=
match b with
| &T => (z,0,0,0,0,0,0)%Z
| &L => (0,z,0,0,0,0,0)%Z
| &M => (0,0,z,0,0,0,0)%Z
| &I => (0,0,0,z,0,0,0)%Z
| &Q => (0,0,0,0,z,0,0)%Z
| &N => (0,0,0,0,0,z,0)%Z
| &J => (0,0,0,0,0,0,z)%Z
end.
match b with
| &T => (z,0,0,0,0,0,0)%Z
| &L => (0,z,0,0,0,0,0)%Z
| &M => (0,0,z,0,0,0,0)%Z
| &I => (0,0,0,z,0,0,0)%Z
| &Q => (0,0,0,0,z,0,0)%Z
| &N => (0,0,0,0,0,z,0)%Z
| &J => (0,0,0,0,0,0,z)%Z
end.
Definition dAll (d : Dims) (P : Z -> Prop) : Prop.
des_dims1 d.
exact (P a /\ P a0 /\ P a1 /\ P a2 /\ P a3 /\ P a4 /\ P a5).
Defined.
des_dims1 d.
exact (P a /\ P a0 /\ P a1 /\ P a2 /\ P a3 /\ P a4 /\ P a5).
Defined.
All components of Dims is true for (P : Z -> bool)
Definition dAllb (d : Dims) (P : Z -> bool) : bool.
des_dims1 d.
exact (P a && P a0 && P a1 && P a2 && P a3 && P a4 && P a5).
Defined.
des_dims1 d.
exact (P a && P a0 && P a1 && P a2 && P a3 && P a4 && P a5).
Defined.
Definition dimFromDims (d : Dims) (b : BaseUnit) : Z.
des_dims1 d.
exact (match b with
| &T => a | &L => a0 | &M => a1 | &I => a2
| &Q => a3 | &N => a4 | &J => a5
end).
Defined.
des_dims1 d.
exact (match b with
| &T => a | &L => a0 | &M => a1 | &I => a2
| &Q => a3 | &N => a4 | &J => a5
end).
Defined.
Definition dmap (d : Dims) (f : Z -> Z) : Dims.
des_dims1 d.
exact (f a, f a0, f a1, f a2, f a3, f a4, f a5).
Defined.
des_dims1 d.
exact (f a, f a0, f a1, f a2, f a3, f a4, f a5).
Defined.
Mapping binary function `f` to Dims `d1` and `d2`
Definition dmap2 (d1 d2 : Dims) (f : Z -> Z -> Z) : Dims.
des_dims2 d1 d2.
exact (f a b, f a0 b0, f a1 b1, f a2 b2, f a3 b3, f a4 b4, f a5 b5).
Defined.
des_dims2 d1 d2.
exact (f a b, f a0 b0, f a1 b1, f a2 b2, f a3 b3, f a4 b4, f a5 b5).
Defined.
dmap2 is commutative, if the operation is.
Lemma dmap2_comm : forall d1 d2 f,
(forall a b, f a b = f b a) ->
dmap2 d1 d2 f = dmap2 d2 d1 f.
Proof.
intros. unfold dmap2. des_dims2 d1 d2; simpl. repeat (f_equal; auto).
Qed.
(forall a b, f a b = f b a) ->
dmap2 d1 d2 f = dmap2 d2 d1 f.
Proof.
intros. unfold dmap2. des_dims2 d1 d2; simpl. repeat (f_equal; auto).
Qed.
dmap2 is associative, if the operation is.
Lemma dmap2_assoc : forall d1 d2 d3 f,
(forall a b c, f (f a b) c = f a (f b c)) ->
dmap2 (dmap2 d1 d2 f) d3 f = dmap2 d1 (dmap2 d2 d3 f) f.
Proof.
intros. unfold dmap2. des_dims3 d1 d2 d3. repeat (f_equal; auto).
Qed.
(forall a b c, f (f a b) c = f a (f b c)) ->
dmap2 (dmap2 d1 d2 f) d3 f = dmap2 d1 (dmap2 d2 d3 f) f.
Proof.
intros. unfold dmap2. des_dims3 d1 d2 d3. repeat (f_equal; auto).
Qed.
dmap2 has left identity, if the operation does.
Lemma dmap2_0_l : forall d f, (forall a, f 0 a = a)%Z -> dmap2 dzero d f = d.
Proof. intros. des_dims1 d; simpl. repeat (f_equal; auto). Qed.
Proof. intros. des_dims1 d; simpl. repeat (f_equal; auto). Qed.
dmap2 has right identity, if the operation does.
Lemma dmap2_0_r : forall d f, (forall a, f a 0 = a)%Z -> dmap2 d dzero f = d.
Proof. intros. des_dims1 d; simpl. repeat (f_equal; auto). Qed.
Proof. intros. des_dims1 d; simpl. repeat (f_equal; auto). Qed.
dmap2 has left inverse, if the operation does.
Lemma dmap2_inv_l : forall d f g, (forall a, f (g a) a = 0)%Z -> dmap2 (dmap d g) d f = dzero.
Proof. intros. des_dims1 d; simpl. unfold dzero. repeat (f_equal; auto). Qed.
Proof. intros. des_dims1 d; simpl. unfold dzero. repeat (f_equal; auto). Qed.
dmap2 has right inverse, if the operation does.
Lemma dmap2_inv_r : forall d f g, (forall a, f a (g a) = 0)%Z -> dmap2 d (dmap d g) f = dzero.
Proof. intros. des_dims1 d; simpl. unfold dzero. repeat (f_equal; auto). Qed.
Proof. intros. des_dims1 d; simpl. unfold dzero. repeat (f_equal; auto). Qed.
dmap2 cancel law on left
Lemma dmap2_cancel_l : forall d d1 d2 f,
(forall a b c : Z, (f a b = f a c)%Z -> b = c) ->
dmap2 d d1 f = dmap2 d d2 f <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
des_dims3 d d1 d2. simpl in H0. inversion H0.
apply H in H2,H3,H4,H5,H6,H7,H8. repeat f_equal; auto.
Qed.
(forall a b c : Z, (f a b = f a c)%Z -> b = c) ->
dmap2 d d1 f = dmap2 d d2 f <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
des_dims3 d d1 d2. simpl in H0. inversion H0.
apply H in H2,H3,H4,H5,H6,H7,H8. repeat f_equal; auto.
Qed.
dmap2 cancel law on right
Lemma dmap2_cancel_r : forall d d1 d2 f,
(forall a b c : Z, (f a c = f b c)%Z -> a = b) ->
dmap2 d1 d f = dmap2 d2 d f <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
des_dims3 d d1 d2. simpl in H0. inversion H0.
apply H in H2,H3,H4,H5,H6,H7,H8. repeat f_equal; auto.
Qed.
(forall a b c : Z, (f a c = f b c)%Z -> a = b) ->
dmap2 d1 d f = dmap2 d2 d f <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
des_dims3 d d1 d2. simpl in H0. inversion H0.
apply H in H2,H3,H4,H5,H6,H7,H8. repeat f_equal; auto.
Qed.
dplus is commutative.
Lemma dplus_comm : forall (d1 d2 : Dims), dplus d1 d2 = dplus d2 d1.
Proof. intros. apply dmap2_comm. auto with zarith. Qed.
Proof. intros. apply dmap2_comm. auto with zarith. Qed.
dplus is associative.
Lemma dplus_assoc : forall (d1 d2 d3 : Dims),
dplus (dplus d1 d2) d3 = dplus d1 (dplus d2 d3).
Proof. intros. apply dmap2_assoc. auto with zarith. Qed.
dplus (dplus d1 d2) d3 = dplus d1 (dplus d2 d3).
Proof. intros. apply dmap2_assoc. auto with zarith. Qed.
0 + d = d
Lemma dplus_0_l : forall d, dplus dzero d = d.
Proof. intros. apply dmap2_0_l. auto with zarith. Qed.
Proof. intros. apply dmap2_0_l. auto with zarith. Qed.
d + 0 = d
Lemma dplus_0_r : forall d, dplus d dzero = d.
Proof. intros. apply dmap2_0_r. auto with zarith. Qed.
Proof. intros. apply dmap2_0_r. auto with zarith. Qed.
d + d1 = d + d2 -> d1 = d2
Lemma dplus_cancel_l : forall d d1 d2, dplus d d1 = dplus d d2 <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
apply dmap2_cancel_l in H; auto. intros. lia.
Qed.
Proof.
intros. split; intros; [| subst; auto].
apply dmap2_cancel_l in H; auto. intros. lia.
Qed.
d1 + d = d2 + d -> d1 = d2
Lemma dplus_cancel_r : forall d d1 d2, dplus d1 d = dplus d2 d <-> d1 = d2.
Proof.
intros. split; intros; [| subst; auto].
apply dmap2_cancel_r in H; auto. intros. lia.
Qed.
Proof.
intros. split; intros; [| subst; auto].
apply dmap2_cancel_r in H; auto. intros. lia.
Qed.
((d + d1) =? (d + d2)) = (d1 =? d2)
Lemma deqb_dplus_cancel_l : forall d1 d2 d,
deqb (dplus d d1) (dplus d d2) = deqb d1 d2.
Proof.
intros. bdestruct (deqb d1 d2).
- subst. apply deqb_refl.
- apply deqb_false_iff. intro. apply dplus_cancel_l in H0. easy.
Qed.
deqb (dplus d d1) (dplus d d2) = deqb d1 d2.
Proof.
intros. bdestruct (deqb d1 d2).
- subst. apply deqb_refl.
- apply deqb_false_iff. intro. apply dplus_cancel_l in H0. easy.
Qed.
((d1 + d) =? (d2 + d)) = (d1 =? d2)
Lemma deqb_dplus_cancel_r : forall d1 d2 d,
deqb (dplus d1 d) (dplus d2 d) = deqb d1 d2.
Proof.
intros. bdestruct (deqb d1 d2).
- subst. apply deqb_refl.
- apply deqb_false_iff. intro. apply dplus_cancel_r in H0. easy.
Qed.
deqb (dplus d1 d) (dplus d2 d) = deqb d1 d2.
Proof.
intros. bdestruct (deqb d1 d2).
- subst. apply deqb_refl.
- apply deqb_false_iff. intro. apply dplus_cancel_r in H0. easy.
Qed.
(-d) + d = 0
Lemma dplus_dopp_l (d : Dims) : dplus (dopp d) d = dzero.
Proof. intros. apply dmap2_inv_l. auto with zarith. Qed.
Proof. intros. apply dmap2_inv_l. auto with zarith. Qed.
d + (-d) = 0
Lemma dplus_dopp_r (d1 : Dims) : dplus d1 (dopp d1) = dzero.
Proof. intros. apply dmap2_inv_r. auto with zarith. Qed.
Proof. intros. apply dmap2_inv_r. auto with zarith. Qed.
Scale multiplication of Dims
0 * d = 0
The valid condition for ddiv is every dimension is divisible by `z` (bool)
The valid condition for ddiv is every dimension is divisible by `z` (Prop)
z <> 0 -> (n * d) / n = d
Lemma ddiv_dscal z d : (z <> 0)%Z -> ddiv z (dscal z d) = d.
Proof.
intros. des_dims1 d. lazy [ddiv dscal dmap]. repeat f_equal; auto with Z.
Qed.
Proof.
intros. des_dims1 d. lazy [ddiv dscal dmap]. repeat f_equal; auto with Z.
Qed.
ddivCond z d -> dscal z (ddiv z d) = d
Lemma dscal_ddiv z d : ddivCond z d -> dscal z (ddiv z d) = d.
Proof.
intros. des_dims1 d. lazy [ddiv dscal dmap]. hnf in H. logic.
repeat f_equal; auto with Z.
Qed.
Proof.
intros. des_dims1 d. lazy [ddiv dscal dmap]. hnf in H. logic.
repeat f_equal; auto with Z.
Qed.
Definition udims (u : Unit) : Dims :=
(udim u &T, udim u &L, udim u &M, udim u &I, udim u &Q, udim u &N, udim u &J).
Section udims_spec.
Infix "+" := dplus.
(udim u &T, udim u &L, udim u &M, udim u &I, udim u &Q, udim u &N, udim u &J).
Section udims_spec.
Infix "+" := dplus.
Verify the consistent with dmakeByBU
Lemma udims_spec : forall u,
let dimByBU b : Dims := dmakeByBU b (udim u b) in
udims u =
(dimByBU &T) + (dimByBU &L) + (dimByBU &M) + (dimByBU &N) +
(dimByBU &J) + (dimByBU &Q) + (dimByBU &I).
Proof.
intros. unfold udims, dimByBU. simpl.
repeat f_equal; auto with zarith.
Qed.
End udims_spec.
let dimByBU b : Dims := dmakeByBU b (udim u b) in
udims u =
(dimByBU &T) + (dimByBU &L) + (dimByBU &M) + (dimByBU &N) +
(dimByBU &J) + (dimByBU &Q) + (dimByBU &I).
Proof.
intros. unfold udims, dimByBU. simpl.
repeat f_equal; auto with zarith.
Qed.
End udims_spec.
Two udims equal, iff its components equal (Prop version)
Lemma udims_eq_iffP : forall u1 u2,
udims u1 = udims u2 <->
udim u1 &T = udim u2 &T /\
udim u1 &L = udim u2 &L /\
udim u1 &M = udim u2 &M /\
udim u1 &I = udim u2 &I /\
udim u1 &Q = udim u2 &Q /\
udim u1 &N = udim u2 &N /\
udim u1 &J = udim u2 &J.
Proof.
intros. unfold udims. split; intros.
- inversion H. repeat split; auto.
- do 6 destruct H as [? H]. repeat (f_equal; auto).
Qed.
udims u1 = udims u2 <->
udim u1 &T = udim u2 &T /\
udim u1 &L = udim u2 &L /\
udim u1 &M = udim u2 &M /\
udim u1 &I = udim u2 &I /\
udim u1 &Q = udim u2 &Q /\
udim u1 &N = udim u2 &N /\
udim u1 &J = udim u2 &J.
Proof.
intros. unfold udims. split; intros.
- inversion H. repeat split; auto.
- do 6 destruct H as [? H]. repeat (f_equal; auto).
Qed.
Two udims equal, iff its components equal (bool version)
Lemma udims_eq_iffb : forall u1 u2,
udims u1 = udims u2 <->
(udim u1 &T =? udim u2 &T)%Z &&
(udim u1 &L =? udim u2 &L)%Z &&
(udim u1 &M =? udim u2 &M)%Z &&
(udim u1 &I =? udim u2 &I)%Z &&
(udim u1 &Q =? udim u2 &Q)%Z &&
(udim u1 &N =? udim u2 &N)%Z &&
(udim u1 &J =? udim u2 &J)%Z = true.
Proof.
intros. rewrite udims_eq_iffP.
rewrite !andb_true_iff. rewrite !Z.eqb_eq. tauto.
Qed.
udims u1 = udims u2 <->
(udim u1 &T =? udim u2 &T)%Z &&
(udim u1 &L =? udim u2 &L)%Z &&
(udim u1 &M =? udim u2 &M)%Z &&
(udim u1 &I =? udim u2 &I)%Z &&
(udim u1 &Q =? udim u2 &Q)%Z &&
(udim u1 &N =? udim u2 &N)%Z &&
(udim u1 &J =? udim u2 &J)%Z = true.
Proof.
intros. rewrite udims_eq_iffP.
rewrite !andb_true_iff. rewrite !Z.eqb_eq. tauto.
Qed.
Lemma udims_Unone : forall r : R, udims (Unone r) = dzero.
Proof. intros. unfold udims. simpl. auto. Qed.
Proof. intros. unfold udims. simpl. auto. Qed.
Lemma udims_Ubu : forall b, udims (Ubu b) = dmakeByBU b 1.
Proof. unfold udims. destruct b; simpl; auto. Qed.
Proof. unfold udims. destruct b; simpl; auto. Qed.
Lemma udims_Umul : forall u1 u2, udims (u1 * u2) = dplus (udims u1) (udims u2).
Proof. intros. unfold udims. simpl. auto. Qed.
Proof. intros. unfold udims. simpl. auto. Qed.
Lemma udims_upow : forall u z, udims (u ^ z) = dscal z (udims u).
Proof.
intros. simpl. unfold udims.
repeat f_equal; rewrite udim_upow; auto with zarith.
Qed.
Proof.
intros. simpl. unfold udims.
repeat f_equal; rewrite udim_upow; auto with zarith.
Qed.
Lemma udims_ucons : forall u b z, udims (ucons u b z) = dplus (udims u) (dmakeByBU b z).
Proof.
intros. simpl. unfold udims.
destruct b; simpl; simp_udim; repeat f_equal; auto with zarith.
Qed.
Proof.
intros. simpl. unfold udims.
destruct b; simpl; simp_udim; repeat f_equal; auto with zarith.
Qed.
Definition Nunit := (R * Dims)%type.
Definition ncoef (n : Nunit) : R := fst n.
Definition ndims (n : Nunit) : Dims := snd n.
Definition ncoef (n : Nunit) : R := fst n.
Definition ndims (n : Nunit) : Dims := snd n.
Nunit of no-dimensional
Lemma neq_iff : forall n1 n2 : Nunit,
n1 = n2 <-> ncoef n1 = ncoef n2 /\ ndims n1 = ndims n2.
Proof. intros. destruct n1, n2. simpl in *. apply pair_eq2. Qed.
n1 = n2 <-> ncoef n1 = ncoef n2 /\ ndims n1 = ndims n2.
Proof. intros. destruct n1, n2. simpl in *. apply pair_eq2. Qed.
Nunit not equal, iff coefficient or dimensions not equal.
Lemma nneq_iff : forall n1 n2 : Nunit,
n1 <> n2 <-> (ncoef n1 <> ncoef n2) \/ (ndims n1 <> ndims n2).
Proof. intros. rewrite neq_iff. tauto. Qed.
n1 <> n2 <-> (ncoef n1 <> ncoef n2) \/ (ndims n1 <> ndims n2).
Proof. intros. rewrite neq_iff. tauto. Qed.
Boolean equality of Nunit
neqb = true is reflexive
Lemma neqb_refl n1 : neqb n1 n1 = true.
Proof. unfold neqb. rewrite andb_true_iff, Reqb_true, deqb_true_iff; auto. Qed.
Proof. unfold neqb. rewrite andb_true_iff, Reqb_true, deqb_true_iff; auto. Qed.
neqb is true, iff eq.
Lemma neqb_true_iff n1 n2 : (neqb n1 n2 = true) <-> n1 = n2.
Proof.
unfold neqb. rewrite !andb_true_iff.
rewrite Reqb_true, deqb_true_iff. rewrite neq_iff. easy.
Qed.
Proof.
unfold neqb. rewrite !andb_true_iff.
rewrite Reqb_true, deqb_true_iff. rewrite neq_iff. easy.
Qed.
neqb is false, iff not eq
Lemma neqb_false_iff n1 n2 : (neqb n1 n2 = false) <-> (n1 <> n2).
Proof. intros. rewrite <- neqb_true_iff. split; solve_bool. Qed.
Lemma neqb_reflect : forall n1 n2, reflect (n1 = n2) (neqb n1 n2).
Proof.
intros. destruct (neqb n1 n2) eqn:E1; constructor.
apply neqb_true_iff; auto. apply neqb_false_iff; auto.
Qed.
Hint Resolve neqb_reflect : bdestruct.
Proof. intros. rewrite <- neqb_true_iff. split; solve_bool. Qed.
Lemma neqb_reflect : forall n1 n2, reflect (n1 = n2) (neqb n1 n2).
Proof.
intros. destruct (neqb n1 n2) eqn:E1; constructor.
apply neqb_true_iff; auto. apply neqb_false_iff; auto.
Qed.
Hint Resolve neqb_reflect : bdestruct.
Nunit eq is decidable
neqb is commutative.
Lemma neqb_comm n1 n2 : neqb n1 n2 = neqb n2 n1.
Proof. bdestruct (neqb n1 n2); bdestruct (neqb n2 n1); auto; congruence. Qed.
Proof. bdestruct (neqb n1 n2); bdestruct (neqb n2 n1); auto; congruence. Qed.
Multiplication of Nunit
Definition nmul (n1 n2 : Nunit) : Nunit :=
((ncoef n1 * ncoef n2)%R, dplus (ndims n1) (ndims n2)).
Lemma nmul_comm (n1 n2 : Nunit) : nmul n1 n2 = nmul n2 n1.
Proof.
destruct n1,n2. unfold nmul; simpl.
rewrite Rmult_comm, dplus_comm; auto.
Qed.
Lemma nmul_assoc (n1 n2 n3 : Nunit) : nmul (nmul n1 n2) n3 = nmul n1 (nmul n2 n3).
Proof.
destruct n1,n2,n3. unfold nmul; simpl.
rewrite Rmult_assoc, dplus_assoc; auto.
Qed.
Lemma nmul_1_l (n : Nunit) : nmul nunitOne n = n.
Proof. cbv. destruct n. des_dims1 d. f_equal. lra. Qed.
Lemma nmul_1_r (n : Nunit) : nmul n nunitOne = n.
Proof. intros. rewrite nmul_comm. apply nmul_1_l. Qed.
Inverse of Nunit
Definition ninv (n1 : Nunit) : Nunit := (Rinv (ncoef n1), dopp (ndims n1)).
Lemma nmul_ninv_l : forall n : Nunit, ncoef n <> 0 -> nmul (ninv n) n = nunitOne.
Proof.
intros. destruct n. des_dims1 d. unfold ninv, nmul, nunitOne, dzero. cbn.
f_equal. field. auto. repeat f_equal; lia.
Qed.
Lemma nmul_ninv_r : forall n : Nunit, ncoef n <> 0 -> nmul n (ninv n) = nunitOne.
Proof.
intros. destruct n. des_dims1 d. unfold ninv, nmul, nunitOne, dzero. cbn.
f_equal. field. auto. repeat f_equal; lia.
Qed.
Lemma nmul_ninv_l : forall n : Nunit, ncoef n <> 0 -> nmul (ninv n) n = nunitOne.
Proof.
intros. destruct n. des_dims1 d. unfold ninv, nmul, nunitOne, dzero. cbn.
f_equal. field. auto. repeat f_equal; lia.
Qed.
Lemma nmul_ninv_r : forall n : Nunit, ncoef n <> 0 -> nmul n (ninv n) = nunitOne.
Proof.
intros. destruct n. des_dims1 d. unfold ninv, nmul, nunitOne, dzero. cbn.
f_equal. field. auto. repeat f_equal; lia.
Qed.
Division of Nunit
Integer power of a Nunit
npow n 2 = nmul n n
Lemma npow2_eq_nmul : forall (n : Nunit), npow n 2 = nmul n n.
Proof.
intros. unfold npow, nmul. f_equal.
- cbv. ra.
- destruct n. des_dims1 d.
lazy [dscal dmap ndims snd dplus dmap2]. repeat (f_equal; try lia).
Qed.
Proof.
intros. unfold npow, nmul. f_equal.
- cbv. ra.
- destruct n. des_dims1 d.
lazy [dscal dmap ndims snd dplus dmap2]. repeat (f_equal; try lia).
Qed.
Condition of nroot is that: z is positive && d is divisible by n (Proposition)
Condition of nroot is that: z is positive && d is divisible by n (boolean)
nroot (npow n z) z = n
Lemma nroot_npow : forall n z, (0 < z)%Z -> 0 < ncoef n -> nroot (npow n z) z = n.
Proof.
intros. destruct n. des_dims1 d. unfold nroot. f_equal.
- simpl. unfold Z2R. apply Rpower_powerRZ_inv; auto. lia.
- simpl. assert (z <> 0)%Z by lia. repeat f_equal; auto with Z.
Qed.
Proof.
intros. destruct n. des_dims1 d. unfold nroot. f_equal.
- simpl. unfold Z2R. apply Rpower_powerRZ_inv; auto. lia.
- simpl. assert (z <> 0)%Z by lia. repeat f_equal; auto with Z.
Qed.
npow (nroot n z) z = n
Lemma npow_nroot : forall n z,
(0 < z)%Z -> 0 < ncoef n -> nrootCond n z -> npow (nroot n z) z = n.
Proof.
intros. destruct n. des_dims1 d. unfold npow, nroot in *. simpl in *. f_equal.
- unfold Z2R. apply powerRZ_Rpower_inv; auto. lia.
- unfold nrootCond in H1. simpl in H1. logic. repeat f_equal; auto with Z.
Qed.
(0 < z)%Z -> 0 < ncoef n -> nrootCond n z -> npow (nroot n z) z = n.
Proof.
intros. destruct n. des_dims1 d. unfold npow, nroot in *. simpl in *. f_equal.
- unfold Z2R. apply powerRZ_Rpower_inv; auto. lia.
- unfold nrootCond in H1. simpl in H1. logic. repeat f_equal; auto with Z.
Qed.
nroot 2 (nmul n n) = n
Lemma nroot2_nmul : forall n, 0 < ncoef n -> nroot (nmul n n) 2 = n.
Proof.
intros. replace (nmul n n) with (npow n 2). apply nroot_npow; auto. lia.
rewrite npow2_eq_nmul. auto.
Qed.
Proof.
intros. replace (nmul n n) with (npow n 2). apply nroot_npow; auto. lia.
rewrite npow2_eq_nmul. auto.
Qed.
npow (nroot 2 n) 2 = n
Lemma npow_nroot2 : forall n, 0 < ncoef n -> nrootCond n 2 -> npow (nroot n 2) 2 = n.
Proof. intros. apply npow_nroot; auto; try lia. Qed.
Proof. intros. apply npow_nroot; auto; try lia. Qed.
Definition u2n (u : Unit) : Nunit := (ucoef u, udims u).
Section test.
Let m : Unit := &L.
Let s : Unit := &T.
Let u1 : Unit := 1 * m * s.
Let u2 : Unit := s * 1 * m.
Goal npow (u2n (10 * m)) 3 = u2n (1000 * m * m * m).
Proof. cbv. f_equal. lra. Qed.
Goal npow (u2n (10 * m)) 3 = u2n (1000 * m * m * m).
Proof. cbv. f_equal. lra. Qed.
End test.
Section test.
Let m : Unit := &L.
Let s : Unit := &T.
Let u1 : Unit := 1 * m * s.
Let u2 : Unit := s * 1 * m.
Goal npow (u2n (10 * m)) 3 = u2n (1000 * m * m * m).
Proof. cbv. f_equal. lra. Qed.
Goal npow (u2n (10 * m)) 3 = u2n (1000 * m * m * m).
Proof. cbv. f_equal. lra. Qed.
End test.
Dimension of u2n u has known form
Lemma udim_u2n : forall u,
let '(coef, (ds, dm, dkg, dA, dK, dmol, dcd)) := u2n u in
udim u &T = ds /\
udim u &L = dm /\
udim u &M = dkg /\
udim u &I = dA /\
udim u &Q = dK /\
udim u &N = dmol /\
udim u &J = dcd.
Proof. intros. simpl. repeat split; auto. Qed.
let '(coef, (ds, dm, dkg, dA, dK, dmol, dcd)) := u2n u in
udim u &T = ds /\
udim u &L = dm /\
udim u &M = dkg /\
udim u &I = dA /\
udim u &Q = dK /\
udim u &N = dmol /\
udim u &J = dcd.
Proof. intros. simpl. repeat split; auto. Qed.
Lemma ndims_u2n u : ndims (u2n u) = udims u.
Proof.
destruct (u2n u) as [c d] eqn:H. des_dims1 d. unfold ndims, udims.
pose proof (udim_u2n u). rewrite H in H0. logic. simpl. subst. auto.
Qed.
Proof.
destruct (u2n u) as [c d] eqn:H. des_dims1 d. unfold ndims, udims.
pose proof (udim_u2n u). rewrite H in H0. logic. simpl. subst. auto.
Qed.
u2n of b.
Lemma u2n_Ubu : forall b, u2n (Ubu b) = (1, dmakeByBU b 1).
Proof. intros. unfold u2n. f_equal. simpl. rewrite udims_Ubu. auto. Qed.
Proof. intros. unfold u2n. f_equal. simpl. rewrite udims_Ubu. auto. Qed.
Lemma u2n_Umult : forall (u1 u2 : Unit),
u2n (u1 * u2) =
((ncoef (u2n u1) * ncoef (u2n u2))%R,
dplus (ndims (u2n u1)) (ndims (u2n u2))).
Proof. intros. simpl. reflexivity. Qed.
Lemma u2n_Umult_cancel_l : forall u1 u2 u,
u2n u1 = u2n u2 -> u2n (u * u1) = u2n (u * u2).
Proof.
intros. rewrite !u2n_Umult. destruct (u2n u1),(u2n u2),(u2n u).
rewrite neq_iff in *; simpl in *. destruct H; subst. auto.
Qed.
Lemma u2n_Umult_cancel_r : forall u1 u2 u,
u2n u1 = u2n u2 -> u2n (u1 * u) = u2n (u2 * u).
Proof.
intros. rewrite !u2n_Umult. destruct (u2n u1),(u2n u2),(u2n u).
rewrite neq_iff in *; simpl in *. destruct H; subst. auto.
Qed.
u2n (u1 * u2) =
((ncoef (u2n u1) * ncoef (u2n u2))%R,
dplus (ndims (u2n u1)) (ndims (u2n u2))).
Proof. intros. simpl. reflexivity. Qed.
Lemma u2n_Umult_cancel_l : forall u1 u2 u,
u2n u1 = u2n u2 -> u2n (u * u1) = u2n (u * u2).
Proof.
intros. rewrite !u2n_Umult. destruct (u2n u1),(u2n u2),(u2n u).
rewrite neq_iff in *; simpl in *. destruct H; subst. auto.
Qed.
Lemma u2n_Umult_cancel_r : forall u1 u2 u,
u2n u1 = u2n u2 -> u2n (u1 * u) = u2n (u2 * u).
Proof.
intros. rewrite !u2n_Umult. destruct (u2n u1),(u2n u2),(u2n u).
rewrite neq_iff in *; simpl in *. destruct H; subst. auto.
Qed.
Lemma u2n_Umult_wd u1 u2 u3 u4 :
u2n u1 = u2n u2 -> u2n u3 = u2n u4 ->
u2n (u1 * u3) = u2n (u2 * u4).
Proof.
intros. rewrite !u2n_Umult.
destruct (u2n u1), (u2n u2), (u2n u3), (u2n u4).
inversion H. inversion H0. auto.
Qed.
u2n u1 = u2n u2 -> u2n u3 = u2n u4 ->
u2n (u1 * u3) = u2n (u2 * u4).
Proof.
intros. rewrite !u2n_Umult.
destruct (u2n u1), (u2n u2), (u2n u3), (u2n u4).
inversion H. inversion H0. auto.
Qed.
Lemma u2n_Uinv : forall u,
u2n (/u) = ((/(ncoef (u2n u)))%R, dopp (ndims (u2n u))).
Proof. easy. Qed.
u2n (/u) = ((/(ncoef (u2n u)))%R, dopp (ndims (u2n u))).
Proof. easy. Qed.
Lemma u2n_Uinv_wd u1 u2 : u2n u1 = u2n u2 -> u2n (/u1) = u2n (/u2).
Proof.
intros. rewrite !u2n_Uinv. destruct (u2n u1), (u2n u2).
inversion H. simpl in *. auto.
Qed.
Proof.
intros. rewrite !u2n_Uinv. destruct (u2n u1), (u2n u2).
inversion H. simpl in *. auto.
Qed.
Lemma u2n_upowNat_wd u1 u2 n :
u2n u1 = u2n u2 -> u2n (upowNat u1 n) = u2n (upowNat u2 n).
Proof.
intros. induction n; simpl; auto. destruct n; auto.
apply u2n_Umult_wd; auto.
Qed.
u2n u1 = u2n u2 -> u2n (upowNat u1 n) = u2n (upowNat u2 n).
Proof.
intros. induction n; simpl; auto. destruct n; auto.
apply u2n_Umult_wd; auto.
Qed.
Lemma ucoef_upowNat u n : ucoef (upowNat u n) = pow (ncoef (u2n u)) n.
Proof.
intros. induction n; simpl; auto. destruct n.
- simpl. rewrite <- ncoef_u2n. simpl. ring.
- rewrite ucoef_Umul. rewrite IHn. rewrite <- ncoef_u2n; simpl. auto.
Qed.
Proof.
intros. induction n; simpl; auto. destruct n.
- simpl. rewrite <- ncoef_u2n. simpl. ring.
- rewrite ucoef_Umul. rewrite IHn. rewrite <- ncoef_u2n; simpl. auto.
Qed.
u2n is compatible for Upow.
Lemma u2n_Upow_wd u1 u2 z : u2n u1 = u2n u2 -> u2n (u1 ^ z) = u2n (u2 ^ z).
Proof.
intros. unfold upow. destruct z; auto.
- apply u2n_upowNat_wd. auto.
- apply u2n_Uinv_wd. apply u2n_upowNat_wd. auto.
Qed.
Proof.
intros. unfold upow. destruct z; auto.
- apply u2n_upowNat_wd. auto.
- apply u2n_Uinv_wd. apply u2n_upowNat_wd. auto.
Qed.
Lemma ucoef_upow u z : ucoef (upow u z) = powerRZ (ncoef (u2n u)) z.
Proof.
intros. unfold upow. destruct z; auto.
- apply ucoef_upowNat.
- simpl. f_equal. apply ucoef_upowNat.
Qed.
Proof.
intros. unfold upow. destruct z; auto.
- apply ucoef_upowNat.
- simpl. f_equal. apply ucoef_upowNat.
Qed.
Lemma u2n_upow_rw u z :
u2n (u ^ z) = (powerRZ (ncoef (u2n u)) z, dscal z (ndims (u2n u))).
Proof.
intros. apply neq_iff; simpl. split.
apply ucoef_upow. apply udims_upow.
Qed.
u2n (u ^ z) = (powerRZ (ncoef (u2n u)) z, dscal z (ndims (u2n u))).
Proof.
intros. apply neq_iff; simpl. split.
apply ucoef_upow. apply udims_upow.
Qed.
Definition n2u (n : Nunit) : Unit :=
let '(coef, (ds, dm, dkg, dA, dK, dmol, dcd)) := n in
let u := Unone coef in
let u := ucons u &T ds in
let u := ucons u &L dm in
let u := ucons u &M dkg in
let u := ucons u &I dA in
let u := ucons u &Q dK in
let u := ucons u &N dmol in
let u := ucons u &J dcd in
u.
let '(coef, (ds, dm, dkg, dA, dK, dmol, dcd)) := n in
let u := Unone coef in
let u := ucons u &T ds in
let u := ucons u &L dm in
let u := ucons u &M dkg in
let u := ucons u &I dA in
let u := ucons u &Q dK in
let u := ucons u &N dmol in
let u := ucons u &J dcd in
u.
Lemma ucoef_n2u : forall n, ucoef (n2u n) = ncoef n.
Proof.
intros. destruct n as [c d]. des_dims1 d; simpl. simp_ucoef. auto.
Qed.
Proof.
intros. destruct n as [c d]. des_dims1 d; simpl. simp_ucoef. auto.
Qed.
Dimension of n2u n is the dimension of the n.
Lemma udim_n2u n b : udim (n2u n) b = dimFromDims (ndims n) b.
Proof.
destruct n as [c d]. des_dims1 d. simpl.
destruct b; simp_udim; repeat split; lia.
Qed.
Proof.
destruct n as [c d]. des_dims1 d. simpl.
destruct b; simp_udim; repeat split; lia.
Qed.
Dimension of n2u n is the dimension of the n (extended version).
Lemma udim_n2u_ext n :
let '(_, (ds, dm, dkg, dA, dK, dmol, dcd)) := n in
udim (n2u n) BUTime = ds /\
udim (n2u n) BULength = dm /\
udim (n2u n) BUMass = dkg /\
udim (n2u n) BUElectricCurrent = dA /\
udim (n2u n) BUThermodynamicTemperature = dK /\
udim (n2u n) BUAmountOfSubstance = dmol /\
udim (n2u n) BULuminousIntensity = dcd.
Proof.
destruct n as [? d]. des_dims1 d. simpl. simp_udim. simpl. tauto.
Qed.
let '(_, (ds, dm, dkg, dA, dK, dmol, dcd)) := n in
udim (n2u n) BUTime = ds /\
udim (n2u n) BULength = dm /\
udim (n2u n) BUMass = dkg /\
udim (n2u n) BUElectricCurrent = dA /\
udim (n2u n) BUThermodynamicTemperature = dK /\
udim (n2u n) BUAmountOfSubstance = dmol /\
udim (n2u n) BULuminousIntensity = dcd.
Proof.
destruct n as [? d]. des_dims1 d. simpl. simp_udim. simpl. tauto.
Qed.
Lemma udims_n2u : forall c d, udims (n2u (c, d)) = d.
Proof. intros. unfold udims. des_dims1 d. rewrite !udim_n2u. simpl. auto. Qed.
Proof. intros. unfold udims. des_dims1 d. rewrite !udim_n2u. simpl. auto. Qed.
n2u is injective about coefficient.
Lemma n2u_eq_imply_coef_eq : forall n1 n2,
n2u n1 = n2u n2 -> ncoef n1 = ncoef n2.
Proof. intros. rewrite <- !ucoef_n2u. rewrite H. auto. Qed.
n2u n1 = n2u n2 -> ncoef n1 = ncoef n2.
Proof. intros. rewrite <- !ucoef_n2u. rewrite H. auto. Qed.
n2u is injective about dimensions.
Lemma n2u_eq_imply_dims_eq : forall n1 n2,
n2u n1 = n2u n2 -> ndims n1 = ndims n2.
Proof.
logic. pose proof (udim_n2u_ext n1). rewrite H in H0.
destruct n1 as [c1 d1], n2 as [c2 d2]. des_dims2 d1 d2.
logic. rewrite udim_n2u in *. simpl in *. subst. auto.
Qed.
n2u n1 = n2u n2 -> ndims n1 = ndims n2.
Proof.
logic. pose proof (udim_n2u_ext n1). rewrite H in H0.
destruct n1 as [c1 d1], n2 as [c2 d2]. des_dims2 d1 d2.
logic. rewrite udim_n2u in *. simpl in *. subst. auto.
Qed.
Lemma n2u_eq_iff : forall n1 n2, n2u n1 = n2u n2 <-> n1 = n2.
Proof.
intros n1 n2. split; intros H; subst; auto.
apply neq_iff. split.
apply n2u_eq_imply_coef_eq; auto. apply n2u_eq_imply_dims_eq; auto.
Qed.
Proof.
intros n1 n2. split; intros H; subst; auto.
apply neq_iff. split.
apply n2u_eq_imply_coef_eq; auto. apply n2u_eq_imply_dims_eq; auto.
Qed.
Lemma n2u_neq_iff : forall n1 n2, n2u n1 <> n2u n2 <-> n1 <> n2.
Proof. intros. rewrite <- n2u_eq_iff. easy. Qed.
Proof. intros. rewrite <- n2u_eq_iff. easy. Qed.
Lemma u2n_n2u : forall (n : Nunit), u2n (n2u n) = n.
Proof.
intros n. unfold u2n, udims.
induction n as [c d]. des_dims1 d.
rewrite ucoef_n2u, !udim_n2u. simpl. auto.
Qed.
Proof.
intros n. unfold u2n, udims.
induction n as [c d]. des_dims1 d.
rewrite ucoef_n2u, !udim_n2u. simpl. auto.
Qed.
Lemma ndimb1b_true_iff : forall n, ndim1b n = true <-> n = nunitOne.
Proof. intros. unfold ndim1b. rewrite neqb_true_iff. tauto. Qed.
Proof. intros. unfold ndim1b. rewrite neqb_true_iff. tauto. Qed.
Is a Unit `u` is dimensionless?
Lemma udimb1b_true_iff : forall u, udim1b u = true <-> u2n u = nunitOne.
Proof. intros. unfold udim1b. rewrite neqb_true_iff. tauto. Qed.
Proof. intros. unfold udim1b. rewrite neqb_true_iff. tauto. Qed.
Open Scope Unit_scope.
Boolean Equality of Unit
Definition ueqb (u1 u2 : Unit) : bool := neqb (u2n u1) (u2n u2).
Notation "u1 =? u2" := (ueqb u1 u2) : Unit_scope.
Notation "u1 =? u2" := (ueqb u1 u2) : Unit_scope.
Lemma ueqb_ucons : forall u1 u2 b dim,
ueqb (ucons u1 b dim) (ucons u2 b dim) = ueqb u1 u2.
Proof.
intros. unfold ueqb, neqb. apply andb_eq_inv; auto.
- simpl. simp_ucoef. auto.
- rewrite !ndims_u2n. rewrite !udims_ucons. rewrite deqb_dplus_cancel_r. auto.
Qed.
ueqb (ucons u1 b dim) (ucons u2 b dim) = ueqb u1 u2.
Proof.
intros. unfold ueqb, neqb. apply andb_eq_inv; auto.
- simpl. simp_ucoef. auto.
- rewrite !ndims_u2n. rewrite !udims_ucons. rewrite deqb_dplus_cancel_r. auto.
Qed.
ueqb is true, it is reflexive
ueqb is commutative.
Lemma ueqb_comm (u1 u2 : Unit) : (u1 =? u2)%U = (u2 =? u1)%U.
Proof.
unfold ueqb in *. apply neqb_comm.
Qed.
Proof.
unfold ueqb in *. apply neqb_comm.
Qed.
Lemma ueqb_true_iff : forall (u1 u2 : Unit), u1 =? u2 = true <-> u2n u1 = u2n u2.
Proof. intros. unfold ueqb. apply neqb_true_iff. Qed.
Proof. intros. unfold ueqb. apply neqb_true_iff. Qed.
Lemma ueqb_false_iff : forall (u1 u2 : Unit), u1 =? u2 = false <-> u2n u1 <> u2n u2.
Proof. intros. rewrite <- ueqb_true_iff. split; solve_bool. Qed.
Proof. intros. rewrite <- ueqb_true_iff. split; solve_bool. Qed.
Lemma ueqb_reflect : forall u1 u2, reflect (u2n u1 = u2n u2) (u1 =? u2).
Proof.
intros. destruct (u1 =? u2) eqn:Eu; constructor.
apply ueqb_true_iff; auto. apply ueqb_false_iff; auto.
Qed.
Proof.
intros. destruct (u1 =? u2) eqn:Eu; constructor.
apply ueqb_true_iff; auto. apply ueqb_false_iff; auto.
Qed.
Definition ueq (u1 u2 : Unit) : Prop := u2n u1 = u2n u2.
Infix "==" := (ueq) (at level 70) : Unit_scope.
Infix "==" := (ueq) (at level 70) : Unit_scope.
A tactic for unit equality
Ltac ueq :=
compute; f_equal; try lra; try field.
compute; f_equal; try lra; try field.
Lemma ueq_iff_ueqb u1 u2 : (u1 == u2) <-> (u1 =? u2 = true).
Proof.
unfold ueq, ueqb.
rewrite neqb_true_iff. reflexivity.
Qed.
Proof.
unfold ueq, ueqb.
rewrite neqb_true_iff. reflexivity.
Qed.
Lemma ueq_ucons : forall u1 u2 b dim,
u1 == u2 -> ucons u1 b dim == ucons u2 b dim.
Proof.
intros. rewrite !ueq_iff_ueqb in *.
rewrite ueqb_ucons. auto.
Qed.
u1 == u2 -> ucons u1 b dim == ucons u2 b dim.
Proof.
intros. rewrite !ueq_iff_ueqb in *.
rewrite ueqb_ucons. auto.
Qed.
Equality of two units, iff their coefficients and dimensions all equal.
Lemma ueq_iff_coef_dims : forall (u1 u2 : Unit),
let (c1,d1) := u2n u1 in
let (c2,d2) := u2n u2 in
u1 == u2 <-> c1 = c2 /\ d1 = d2.
Proof. intros. simpl. unfold ueq. rewrite neq_iff. simpl. easy. Qed.
let (c1,d1) := u2n u1 in
let (c2,d2) := u2n u2 in
u1 == u2 <-> c1 = c2 /\ d1 = d2.
Proof. intros. simpl. unfold ueq. rewrite neq_iff. simpl. easy. Qed.
ueq is an equivalence relation.
Lemma ueq_refl : forall (u : Unit), u == u.
Proof. intros. unfold ueq. auto. Qed.
Lemma ueq_sym : forall (u1 u2 : Unit), u1 == u2 -> u2 == u1.
Proof. intros. unfold ueq. auto. Qed.
Lemma ueq_trans : forall (u1 u2 u3 : Unit), u1 == u2 -> u2 == u3 -> u1 == u3.
Proof. intros. unfold ueq in *. rewrite H,H0. auto. Qed.
#[export] Instance ueq_equiv : Equivalence ueq.
Proof.
constructor; hnf; intros; auto.
apply ueq_refl. apply ueq_sym; auto. apply ueq_trans with y; auto.
Qed.
Proof. intros. unfold ueq. auto. Qed.
Lemma ueq_sym : forall (u1 u2 : Unit), u1 == u2 -> u2 == u1.
Proof. intros. unfold ueq. auto. Qed.
Lemma ueq_trans : forall (u1 u2 u3 : Unit), u1 == u2 -> u2 == u3 -> u1 == u3.
Proof. intros. unfold ueq in *. rewrite H,H0. auto. Qed.
#[export] Instance ueq_equiv : Equivalence ueq.
Proof.
constructor; hnf; intros; auto.
apply ueq_refl. apply ueq_sym; auto. apply ueq_trans with y; auto.
Qed.
Definition unit_approx (u1 u2 : Unit) (diff : R) : Prop :=
let (c1, d1) := u2n u1 in
let (c2, d2) := u2n u2 in
(d1 = d2) /\ (Rapprox c1 c2 diff).
let (c1, d1) := u2n u1 in
let (c2, d2) := u2n u2 in
(d1 = d2) /\ (Rapprox c1 c2 diff).
Check if two units is approximate, boolean version.
Definition unit_approxb (u1 u2 : Unit) (diff : R) : bool :=
let (c1, d1) := u2n u1 in
let (c2, d2) := u2n u2 in
(deqb d1 d2) && (Rapproxb c1 c2 diff).
Example unit1 : Unit := (1.5e-100 * &L).
Example unit2 : Unit := (1.6e-100 * &L).
Example diff : R := 0.1e-100.
Goal unit_approxb unit1 unit2 diff = true.
lazy [unit_approxb]. simpl.
unfold Rapproxb, diff. rewrite Rabs_left; ra. autoRbool; ra.
Qed.
let (c1, d1) := u2n u1 in
let (c2, d2) := u2n u2 in
(deqb d1 d2) && (Rapproxb c1 c2 diff).
Example unit1 : Unit := (1.5e-100 * &L).
Example unit2 : Unit := (1.6e-100 * &L).
Example diff : R := 0.1e-100.
Goal unit_approxb unit1 unit2 diff = true.
lazy [unit_approxb]. simpl.
unfold Rapproxb, diff. rewrite Rabs_left; ra. autoRbool; ra.
Qed.
Normalization of Unit
Definition unorm (u : Unit) : Unit := n2u (u2n u).
Section test.
Let m := &L.
Let kg := &M.
Let s := &T.
End test.
Section test.
Let m := &L.
Let kg := &M.
Let s := &T.
End test.
Lemma unorm_complete : forall (u1 u2 : Unit),
(u1 =? u2 = true) -> unorm u1 = unorm u2.
Proof. intros. unfold unorm. apply ueqb_true_iff in H. rewrite H. auto. Qed.
(u1 =? u2 = true) -> unorm u1 = unorm u2.
Proof. intros. unfold unorm. apply ueqb_true_iff in H. rewrite H. auto. Qed.
Every two Unit with same form, have same semantics
Lemma unorm_sound : forall (u1 u2 : Unit),
unorm u1 = unorm u2 -> (u1 =? u2 = true).
Proof.
intros. unfold unorm in *. apply n2u_eq_iff in H.
apply ueqb_true_iff. auto.
Qed.
unorm u1 = unorm u2 -> (u1 =? u2 = true).
Proof.
intros. unfold unorm in *. apply n2u_eq_iff in H.
apply ueqb_true_iff. auto.
Qed.
unorm involution law
Lemma unorm_involutive : forall u : Unit, unorm (unorm u) = unorm u.
Proof. intros. unfold unorm. rewrite u2n_n2u. auto. Qed.
Proof. intros. unfold unorm. rewrite u2n_n2u. auto. Qed.
unorm generate a normalized result
Lemma unorm_unormed : forall u, unormed (unorm u).
Proof. intros. unfold unormed. rewrite unorm_involutive. auto. Qed.
Proof. intros. unfold unormed. rewrite unorm_involutive. auto. Qed.
n2u (1,d) is normalized