Built with Alectryon, running Coq+SerAPI v8.20.0+0.20.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑ Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use instead of Ctrl.
[Loading ML file ssrmatching_plugin.cmxs (using legacy method) ... done]
[Loading ML file ssreflect_plugin.cmxs (using legacy method) ... done]
[Loading ML file ring_plugin.cmxs (using legacy method) ... done]
Serlib plugin: coq-elpi.elpi is not available: serlib support is missing. Incremental checking for commands in this plugin will be impacted.
[Loading ML file coq-elpi.elpi ... done]
Notation "_ + _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ - _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ <= _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ < _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ >= _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ > _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ <= _ <= _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ < _ <= _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ <= _ < _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ < _ < _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Notation "_ * _" was already used in scope nat_scope. [notation-overridden,parsing,default]
Require Export prosa.util.tactics. (** A function to calculate the least common multiple of all integers in a sequence [xs], denoted by [lcml xs]. *) Definition lcml (xs : seq nat) : nat := foldr lcmn 1 xs. (** First we show that [x] divides [lcml (x :: xs)] for any [x] and [xs]. *)

forall (x : nat) (xs : seq nat), x %| lcml (x :: xs)

forall (x : nat) (xs : seq nat), x %| lcml (x :: xs)
x: nat

x %| lcml [:: x]
x, a: nat
xs: seq nat
IHxs: x %| lcml (x :: xs)
x %| lcml [:: x, a & xs]
x: nat

x %| lcml [:: x]
by apply dvdn_lcml.
x, a: nat
xs: seq nat
IHxs: x %| lcml (x :: xs)

x %| lcml [:: x, a & xs]
x, a: nat
xs: seq nat
IHxs: x %| lcml (x :: xs)

x %| lcmn x (lcmn a ((fix foldr (s : seq nat) : nat := match s with | [::] => 1 | x :: s' => lcmn x (foldr s') end) xs))
by apply dvdn_lcml. Qed. (** Similarly, [lcml xs] divides [lcml (x :: xs)] for any [x] and [xs]. *)

forall (x : nat) (xs : seq nat), lcml xs %| lcml (x :: xs)

forall (x : nat) (xs : seq nat), lcml xs %| lcml (x :: xs)
x, a: nat
xs: seq nat
IHxs: lcml xs %| lcml (x :: xs)

lcml (a :: xs) %| lcml [:: x, a & xs]
x, a: nat
xs: seq nat
IHxs: lcml xs %| lcml (x :: xs)

lcmn a ((fix foldr (s : seq nat) : nat := match s with | [::] => 1 | x :: s' => lcmn x (foldr s') end) xs) %| lcmn x ((fix foldr (s : seq nat) : nat := match s with | [::] => 1 | x :: s' => lcmn x (foldr s') end) ([:: a] ++ xs))
by apply dvdn_lcmr. Qed. (** Given a sequence [xs], any integer [x \in xs] divides [lcml xs]. *)

forall (x : nat) (xs : seq nat), x \in xs -> x %| lcml xs

forall (x : nat) (xs : seq nat), x \in xs -> x %| lcml xs
x: nat
xs: seq nat
IN: x \in xs

exists k : nat, lcml xs = k * x
x, z: nat
sq: seq nat
IN: x \in z :: sq
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: (x == z) || (x \in sq)

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
EQ: x = z

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: x \in sq
exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
EQ: x = z

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
EQ: x = z

x %| lcml (z :: sq)
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
EQ: x = z

z %| foldr lcmn 1 (z :: sq)
by apply int_divides_lcm_in_seq.
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: x \in sq

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: x \in sq
k: nat
EQ: lcml sq = k * x

exists k : nat, lcml (z :: sq) = k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: x \in sq
k: nat
EQ: lcml sq = k * x

lcml (z :: sq) = foldr lcmn 1 (z :: sq) %/ foldr lcmn 1 sq * k * x
x, z: nat
sq: seq nat
IH_DIV: x \in sq -> exists k : nat, lcml sq = k * x
IN: x \in sq
k: nat
EQ: lcml sq = k * x

foldr lcmn 1 sq %| foldr lcmn 1 (z :: sq)
by apply lcm_seq_divides_lcm_super. Qed. (** The LCM of all elements in a sequence with only positive elements is positive. *)

forall xs : seq nat, (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs

forall xs : seq nat, (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0

0 < lcml (x :: xs)
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0

(0 < x) && (0 < foldr lcmn 1 xs)
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0

0 < x
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0
0 < foldr lcmn 1 xs
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0

0 < x
by apply POS; rewrite in_cons eq_refl.
x: nat
xs: seq nat
IHxs: (forall x : Datatypes_nat__canonical__eqtype_Equality, x \in xs -> 0 < x) -> 0 < lcml xs
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0

0 < foldr lcmn 1 xs
x: nat
xs: seq nat
POS: forall x0 : Datatypes_nat__canonical__eqtype_Equality, x0 \in x :: xs -> 0 < x0
b: Datatypes_nat__canonical__eqtype_Equality
B_IN: b \in xs

0 < b
by apply POS; rewrite in_cons; apply /orP; right => //. Qed.