Built with Alectryon, running Coq+SerAPI v8.10.0+0.7.0. Coq sources are in this panel; goals and messages will appear in the other. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus.
(************************************************************************) (* * The Coq Proof Assistant / The Coq Development Team *) (* v * INRIA, CNRS and contributors - Copyright 1999-2018 *) (* <O___,, * (see CREDITS file for the list of authors) *) (* \VV/ **************************************************************) (* // * This file is distributed under the terms of the *) (* * GNU Lesser General Public License Version 2.1 *) (* * (see LICENSE file for the text of the license) *) (************************************************************************) Require Import BinInt. Local Open Scope Z_scope.
An alternative power function for Z
This Zpower_alt is extensionally equal to Z.pow,
but not convertible with it. The number of
multiplications is logarithmic instead of linear, but
these multiplications are bigger. Experimentally, it seems
that Zpower_alt is slightly quicker than Z.pow on average,
but can be quite slower on powers of 2.
Definition Zpower_alt n m := match m with | Z0 => 1 | Zpos p => Pos.iter_op Z.mul p n | Zneg p => 0 end. Infix "^^" := Zpower_alt (at level 30, right associativity) : Z_scope.forall f : Z -> Z, (forall x y : Z, f x * y = f (x * y)) -> forall (p : positive) (k : Z), Pos.iter f k p = Pos.iter f 1 p * kforall f : Z -> Z, (forall x y : Z, f x * y = f (x * y)) -> forall (p : positive) (k : Z), Pos.iter f k p = Pos.iter f 1 p * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)forall (p : positive) (k : Z), Pos.iter f k p = Pos.iter f 1 p * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveIHp:forall k0 : Z, Pos.iter f k0 p = Pos.iter f 1 p * k0k:Zf (Pos.iter f (Pos.iter f k p) p) = f (Pos.iter f (Pos.iter f 1 p) p) * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveIHp:forall k0 : Z, Pos.iter f k0 p = Pos.iter f 1 p * k0k:ZPos.iter f (Pos.iter f k p) p = Pos.iter f (Pos.iter f 1 p) p * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)k:Zf k = f 1 * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveIHp:forall k0 : Z, Pos.iter f k0 p = Pos.iter f 1 p * k0k:Zf (Pos.iter f (Pos.iter f k p) p) = f (Pos.iter f (Pos.iter f 1 p) p) * know rewrite !IHp, Hf, Z.mul_assoc.f:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveg:=Pos.iter f 1 p:ZIHp:forall k0 : Z, Pos.iter f k0 p = g * k0k:Zf (Pos.iter f (Pos.iter f k p) p) = f (Pos.iter f g p) * kf:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveIHp:forall k0 : Z, Pos.iter f k0 p = Pos.iter f 1 p * k0k:ZPos.iter f (Pos.iter f k p) p = Pos.iter f (Pos.iter f 1 p) p * know rewrite !IHp, Z.mul_assoc.f:Z -> ZHf:forall x y : Z, f x * y = f (x * y)p:positiveg:=Pos.iter f 1 p:ZIHp:forall k0 : Z, Pos.iter f k0 p = g * k0k:ZPos.iter f (Pos.iter f k p) p = Pos.iter f g p * know rewrite Hf, Z.mul_1_l. Qed.f:Z -> ZHf:forall x y : Z, f x * y = f (x * y)k:Zf k = f 1 * kforall (p : positive) (a : Z), Pos.iter_op Z.mul p (a * a) = Pos.iter_op Z.mul p a * Pos.iter_op Z.mul p aforall (p : positive) (a : Z), Pos.iter_op Z.mul p (a * a) = Pos.iter_op Z.mul p a * Pos.iter_op Z.mul p anow rewrite IHp, Z.mul_shuffle1. Qed.p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p (a0 * a0) = Pos.iter_op Z.mul p a0 * Pos.iter_op Z.mul p a0a:Za * a * Pos.iter_op Z.mul p (a * a * (a * a)) = a * Pos.iter_op Z.mul p (a * a) * (a * Pos.iter_op Z.mul p (a * a))a, b:Za ^^ b = a ^ ba, b:Za ^^ b = a ^ ba:Zp:positivea ^^ Z.pos p = a ^ Z.pos pa:Zp:positivePos.iter_op Z.mul p a = Pos.iter (Z.mul a) 1 pp:positiveforall a : Z, Pos.iter_op Z.mul p a = Pos.iter (Z.mul a) 1 pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Za * Pos.iter_op Z.mul p (a * a) = a * Pos.iter (Z.mul a) (Pos.iter (Z.mul a) 1 p) pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:ZPos.iter_op Z.mul p (a * a) = Pos.iter (Z.mul a) (Pos.iter (Z.mul a) 1 p) pa:Za = a * 1p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Za * Pos.iter_op Z.mul p (a * a) = a * Pos.iter (Z.mul a) (Pos.iter (Z.mul a) 1 p) pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:ZPos.iter_op Z.mul p (a * a) = Pos.iter (Z.mul a) (Pos.iter (Z.mul a) 1 p) pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:ZPos.iter_op Z.mul p (a * a) = Pos.iter (Z.mul a) 1 p * Pos.iter (Z.mul a) 1 pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Zforall x y : Z, a * x * y = a * (x * y)p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Zforall x y : Z, a * x * y = a * (x * y)symmetry; apply Z.mul_assoc.p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa, x, y:Za * x * y = a * (x * y)p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:ZPos.iter_op Z.mul p (a * a) = Pos.iter (Z.mul a) (Pos.iter (Z.mul a) 1 p) pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:ZPos.iter_op Z.mul p (a * a) = Pos.iter (Z.mul a) 1 p * Pos.iter (Z.mul a) 1 pp:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Zforall x y : Z, a * x * y = a * (x * y)p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa:Zforall x y : Z, a * x * y = a * (x * y)symmetry; apply Z.mul_assoc.p:positiveIHp:forall a0 : Z, Pos.iter_op Z.mul p a0 = Pos.iter (Z.mul a0) 1 pa, x, y:Za * x * y = a * (x * y)now Z.nzsimpl. Qed.a:Za = a * 1n:Zn ^^ 0 = 1reflexivity. Qed.n:Zn ^^ 0 = 1a, b:Z0 <= b -> a ^^ Z.succ b = a * a ^^ ba, b:Z0 <= b -> a ^^ Z.succ b = a * a ^^ ba:ZHb:0 <= 0a = a * 1a:Zb:positiveHb:0 <= Z.pos bPos.iter_op Z.mul (b + 1) a = a * Pos.iter_op Z.mul b aa:Zb:positiveHb:0 <= Z.neg ba ^^ Z.pos_sub 1 b = a * 0now Z.nzsimpl.a:ZHb:0 <= 0a = a * 1now rewrite Pos.add_1_r, Pos.iter_op_succ by apply Z.mul_assoc.a:Zb:positiveHb:0 <= Z.pos bPos.iter_op Z.mul (b + 1) a = a * Pos.iter_op Z.mul b anow elim Hb. Qed.a:Zb:positiveHb:0 <= Z.neg ba ^^ Z.pos_sub 1 b = a * 0a, b:Zb < 0 -> a ^^ b = 0now destruct b. Qed.a, b:Zb < 0 -> a ^^ b = 0p, q:positiveZ.pos p ^^ Z.pos q = Z.pos (p ^ q)now rewrite Zpower_equiv, Pos2Z.inj_pow. Qed.p, q:positiveZ.pos p ^^ Z.pos q = Z.pos (p ^ q)