Compute the list of all naturals less than
n
.
Fixpoint up_to_n_listing (n : nat) : list nat := match n with | 0 => [] | S n' => n' :: up_to_n_listing n' end.∀ n : nat, length (up_to_n_listing n) = nby induction n; simpl; congruence. Qed.∀ n : nat, length (up_to_n_listing n) = n∀ n i : nat, i < n ↔ i ∈ up_to_n_listing n∀ n i : nat, i < n ↔ i ∈ up_to_n_listing nn: nat
IHn: ∀ i : nat, i < n ↔ i ∈ up_to_n_listing n
i: nat
H: i < S n
H1: S i ≤ ni ∈ n :: up_to_n_listing nn: nat
IHn: ∀ i : nat, i < n ↔ i ∈ up_to_n_listing n
i: nat
H: i ∈ up_to_n_listing (S n)
H2: i ∈ up_to_n_listing ni < S nby right; apply IHn.n: nat
IHn: ∀ i : nat, i < n ↔ i ∈ up_to_n_listing n
i: nat
H: i < S n
H1: S i ≤ ni ∈ n :: up_to_n_listing nby transitivity n; [apply IHn | lia]. Qed.n: nat
IHn: ∀ i : nat, i < n ↔ i ∈ up_to_n_listing n
i: nat
H: i ∈ up_to_n_listing (S n)
H2: i ∈ up_to_n_listing ni < S n
Given a decidable property on naturals and a bound, finds the
largest natural (not larger the than bound) for which the property holds.
Equations find_largest_nat_with_property_bounded (P : nat -> Prop) `{forall n, Decision (P n)} (bound : nat) : option nat := | P, 0 => None | P, S n => if decide (P n) then Some n else find_largest_nat_with_property_bounded P n.P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) nP: nat → Prop
H: ∀ n : nat, Decision (P n)∀ n : nat, None = Some n ↔ maximal_among lt (λ n0 : nat, n0 < 0 ∧ P n0) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n∀ n : nat, (if decide (P bound) then Some bound else find_largest_nat_with_property_bounded P bound) = Some n ↔ maximal_among lt (λ n0 : nat, n0 < S bound ∧ P n0) nby split; [| intros []; lia].P: nat → Prop
H: ∀ n : nat, Decision (P n)∀ n : nat, None = Some n ↔ maximal_among lt (λ n0 : nat, n0 < 0 ∧ P n0) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n∀ n : nat, (if decide (P bound) then Some bound else find_largest_nat_with_property_bounded P bound) = Some n ↔ maximal_among lt (λ n0 : nat, n0 < S bound ∧ P n0) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: natSome bound = Some n → maximal_among lt (λ n : nat, n < S bound ∧ P n) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: natmaximal_among lt (λ n : nat, n < S bound ∧ P n) n → Some bound = Some nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: natfind_largest_nat_with_property_bounded P bound = Some n → maximal_among lt (λ n : nat, n < S bound ∧ P n) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: natmaximal_among lt (λ n : nat, n < S bound ∧ P n) n → find_largest_nat_with_property_bounded P bound = Some nby intros [= ->]; repeat split; cbn; [lia | | lia].P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: natSome bound = Some n → maximal_among lt (λ n : nat, n < S bound ∧ P n) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: natmaximal_among lt (λ n : nat, n < S bound ∧ P n) n → Some bound = Some nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: nat
Hn: n < S bound
HPn: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → n < m' → m' < nbound = nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: nat
Hn: n < S bound
HPn: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → n < m' → m' < n
l: n < boundbound = nby apply Hmax; [split; [lia |] |].P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: P bound
n: nat
Hn: n < S bound
HPn: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → n < m' → m' < n
l: n < boundbound < nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: natfind_largest_nat_with_property_bounded P bound = Some n → maximal_among lt (λ n : nat, n < S bound ∧ P n) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: natmaximal_among lt (λ n : nat, n < bound ∧ P n) n → maximal_among lt (λ n : nat, n < S bound ∧ P n) nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < bound
H1: P n
Hmax: ∀ m' : nat, m' < bound ∧ P m' → flip lt m' n → flip lt n m'∀ m' : nat, m' < S bound ∧ P m' → flip lt m' n → flip lt n m'P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < bound
H1: P n
Hmax: ∀ m' : nat, m' < bound ∧ P m' → flip lt m' n → flip lt n m'
m: nat
H2: m < S bound
H3: P m
H4: flip lt m nflip lt n mby destruct (decide (m = bound)); [subst | lia].P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < bound
H1: P n
Hmax: ∀ m' : nat, m' < bound ∧ P m' → flip lt m' n → flip lt n m'
m: nat
H2: m < S bound
H3: P m
H4: flip lt m nm < boundP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: natmaximal_among lt (λ n : nat, n < S bound ∧ P n) n → find_largest_nat_with_property_bounded P bound = Some nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < S bound
H1: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → flip lt m' n → flip lt n m'n < boundP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < S bound
H1: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → flip lt m' n → flip lt n m'∀ m' : nat, m' < bound ∧ P m' → flip lt m' n → flip lt n m'by destruct (decide (n = bound)); [subst | lia].P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < S bound
H1: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → flip lt m' n → flip lt n m'n < boundby intros m [] ?; apply Hmax; [split; [lia |] |]. Qed.P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: ∀ n : nat, find_largest_nat_with_property_bounded P bound = Some n ↔ maximal_among lt (λ n0 : nat, n0 < bound ∧ P n0) n
HP: ¬ P bound
n: nat
H0: n < S bound
H1: P n
Hmax: ∀ m' : nat, m' < S bound ∧ P m' → flip lt m' n → flip lt n m'∀ m' : nat, m' < bound ∧ P m' → flip lt m' n → flip lt n m'P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: natfind_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: natfind_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)(if decide (P bound) then Some bound else find_largest_nat_with_property_bounded P bound) = None ↔ (∀ n : nat, n < S bound → ¬ P n)P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: P bound(∀ n : nat, n < S bound → ¬ P n) → Some bound = NoneP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P boundfind_largest_nat_with_property_bounded P bound = None → ∀ n : nat, n < S bound → ¬ P nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P bound(∀ n : nat, n < S bound → ¬ P n) → find_largest_nat_with_property_bounded P bound = Noneby intro Hmax; contradict HP; apply Hmax; lia.P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: P bound(∀ n : nat, n < S bound → ¬ P n) → Some bound = NoneP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P boundfind_largest_nat_with_property_bounded P bound = None → ∀ n : nat, n < S bound → ¬ P nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P bound
H0: find_largest_nat_with_property_bounded P bound = None
n: nat
H1: n < S bound¬ P nby replace n with bound; [| lia].P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P bound
H0: find_largest_nat_with_property_bounded P bound = None
n: nat
H1: n < S bound
n0: ¬ n < bound¬ P nP: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P bound(∀ n : nat, n < S bound → ¬ P n) → find_largest_nat_with_property_bounded P bound = Noneby intros; apply Hmax; lia. Qed.P: nat → Prop
H: ∀ n : nat, Decision (P n)
bound: nat
IHbound: find_largest_nat_with_property_bounded P bound = None ↔ (∀ n : nat, n < bound → ¬ P n)
HP: ¬ P bound
Hmax: ∀ n : nat, n < S bound → ¬ P n∀ n : nat, n < bound → ¬ P n
Given a predicate on indices and naturals, a bound for each index, and a
list of indices, finds first index in the list and largest natural (less than
bound) corresponding to it for which the predicate holds.
Equations find_first_indexed_largest_nat_with_propery_bounded {index} (P : index -> nat -> Prop) `{!RelDecision P} (bound : index -> nat) (indices : list index) : option (index * nat) := | _, _, [] => None | P, bound, i :: indices' with inspect (find_largest_nat_with_property_bounded (P i) (bound i)) => | None eq: Hdec => find_first_indexed_largest_nat_with_propery_bounded P bound indices'; | (Some n) eq: Hdec => Some (i, n).index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
Hindices: NoDup indices∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
Hindices: NoDup indices∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
Hindices: NoDup []∀ (i : index) (n : nat), None = Some (i, n) ↔ i ∈ [] ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, [] = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Hindices: NoDup (a :: indices)
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded_clause_2 (@find_first_indexed_largest_nat_with_propery_bounded) index P RelDecision0 bound a (inspect (find_largest_nat_with_property_bounded (P a) (bound a))) indices = Some (i, n) ↔ i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)by split; [inversion 1 | intros [Hcontra]; inversion Hcontra].index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
Hindices: NoDup []∀ (i : index) (n : nat), None = Some (i, n) ↔ i ∈ [] ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, [] = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Hindices: NoDup (a :: indices)
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded_clause_2 (@find_first_indexed_largest_nat_with_propery_bounded) index P RelDecision0 bound a (inspect (find_largest_nat_with_property_bounded (P a) (bound a))) indices = Some (i, n) ↔ i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded_clause_2 (@find_first_indexed_largest_nat_with_propery_bounded) index P RelDecision0 bound a (inspect (find_largest_nat_with_property_bounded (P a) (bound a))) indices = Some (i, n) ↔ i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _nSome (a, _n) = Some (i, n) → i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) → i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _ni ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None) → Some (a, _n) = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Nonei ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None) → find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _nSome (a, _n) = Some (i, n) → i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
i: index
Ha: i ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
n: nat
Hpos: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
H: Some (i, n) = Some (i, n)∀ prefix suffix : list index, i :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
i: index
Ha: i ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
n: nat
Hpos: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
H: Some (i, n) = Some (i, n)
_i: index
prefix, suffix: list index
Heq: i :: indices = (_i :: prefix) ++ i :: suffix∀ j : index, j ∈ _i :: prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneby apply elem_of_app; right; left.index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
prefix, suffix: list index
_i: index
Hindices: NoDup (prefix ++ _i :: suffix)
IHindices: NoDup (prefix ++ _i :: suffix) → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound (prefix ++ _i :: suffix) = Some (i, n) ↔ i ∈ prefix ++ _i :: suffix ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix0 suffix0 : list index, prefix ++ _i :: suffix = prefix0 ++ i :: suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None)
n: nat
Hpos: find_largest_nat_with_property_bounded (P _i) (bound _i) = Some n_i ∈ prefix ++ _i :: suffixindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) → i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Nonei ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None) → i ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposition: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Nonei ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposition: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposition: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None
_a: index
prefix, suffix: list index
Heq: a :: indices = (_a :: prefix) ++ i :: suffix∀ j : index, j ∈ _a :: prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneby inversion 1; [| eapply Hfirst].index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
i: index
prefix, suffix: list index
IHindices: NoDup (prefix ++ i :: suffix) → ∀ (i0 : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound (prefix ++ i :: suffix) = Some (i0, n) ↔ i0 ∈ prefix ++ i :: suffix ∧ find_largest_nat_with_property_bounded (P i0) (bound i0) = Some n ∧ (∀ prefix0 suffix0 : list index, prefix ++ i :: suffix = prefix0 ++ i0 :: suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None)
Hindices: NoDup (prefix ++ i :: suffix)
_a: index
Ha: _a ∉ prefix ++ i :: suffix
n: nat
Hpos: find_largest_nat_with_property_bounded (P _a) (bound _a) = None
Hi: i ∈ prefix ++ i :: suffix
Hposition: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix0 suffix0 : list index, prefix ++ i :: suffix = prefix0 ++ i :: suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None∀ j : index, j ∈ _a :: prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _ni ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None) → Some (a, _n) = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _n
Hi: i ∈ a :: indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = NoneSome (a, _n) = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _n
Hi: i ∈ indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = NoneSome (a, _n) = Some (i, n)by erewrite Hfirst in Hpos; [| rewrite app_comm_cons | left].index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a, i: index
prefix', suffix: list index
IHindices: NoDup (prefix' ++ i :: suffix) → ∀ (i0 : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound (prefix' ++ i :: suffix) = Some (i0, n) ↔ i0 ∈ prefix' ++ i :: suffix ∧ find_largest_nat_with_property_bounded (P i0) (bound i0) = Some n ∧ (∀ prefix suffix0 : list index, prefix' ++ i :: suffix = prefix ++ [i0] ++ suffix0 → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
Hindices: NoDup (prefix' ++ i :: suffix)
Ha: a ∉ prefix' ++ i :: suffix
n, _n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Some _n
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix0 : list index, a :: prefix' ++ i :: suffix = prefix ++ i :: suffix0 → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = NoneSome (a, _n) = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = Nonei ∈ a :: indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None) → find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ a :: indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Nonei ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → ∀ (i : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound indices = Some (i, n) ↔ i ∈ indices ∧ find_largest_nat_with_property_bounded (P i) (bound i) = Some n ∧ (∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None)
i: index
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ indices
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix suffix : list index, a :: indices = prefix ++ i :: suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = None∀ prefix suffix : list index, indices = prefix ++ [i] ++ suffix → ∀ j : index, j ∈ prefix → find_largest_nat_with_property_bounded (P j) (bound j) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a, i: index
prefix, suffix: list index
IHindices: NoDup (prefix ++ [i] ++ suffix) → ∀ (i0 : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound (prefix ++ [i] ++ suffix) = Some (i0, n) ↔ i0 ∈ prefix ++ [i] ++ suffix ∧ find_largest_nat_with_property_bounded (P i0) (bound i0) = Some n ∧ (∀ prefix0 suffix0 : list index, prefix ++ [i] ++ suffix = prefix0 ++ [i0] ++ suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None)
Hindices: NoDup (prefix ++ [i] ++ suffix)
Ha: a ∉ prefix ++ [i] ++ suffix
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ prefix ++ [i] ++ suffix
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix0 suffix0 : list index, a :: prefix ++ [i] ++ suffix = prefix0 ++ i :: suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None
j: index
Hj: j ∈ prefixfind_largest_nat_with_property_bounded (P j) (bound j) = Noneby rewrite app_comm_cons. Qed.index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a, i: index
prefix, suffix: list index
IHindices: NoDup (prefix ++ [i] ++ suffix) → ∀ (i0 : index) (n : nat), find_first_indexed_largest_nat_with_propery_bounded P bound (prefix ++ [i] ++ suffix) = Some (i0, n) ↔ i0 ∈ prefix ++ [i] ++ suffix ∧ find_largest_nat_with_property_bounded (P i0) (bound i0) = Some n ∧ (∀ prefix0 suffix0 : list index, prefix ++ [i] ++ suffix = prefix0 ++ [i0] ++ suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None)
Hindices: NoDup (prefix ++ [i] ++ suffix)
Ha: a ∉ prefix ++ [i] ++ suffix
n: nat
Hpos: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hi: i ∈ prefix ++ [i] ++ suffix
Hposi: find_largest_nat_with_property_bounded (P i) (bound i) = Some n
Hfirst: ∀ prefix0 suffix0 : list index, a :: prefix ++ [i] ++ suffix = prefix0 ++ i :: suffix0 → ∀ j : index, j ∈ prefix0 → find_largest_nat_with_property_bounded (P j) (bound j) = None
j: index
Hj: j ∈ prefixa :: prefix ++ [i] ++ suffix = (?y :: prefix) ++ i :: ?suffixindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
Hindices: NoDup indicesfind_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
indices: list index
Hindices: NoDup indicesfind_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Hindices: NoDup (a :: indices)
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)find_first_indexed_largest_nat_with_propery_bounded_clause_2 (@find_first_indexed_largest_nat_with_propery_bounded) index P RelDecision0 bound a (inspect (find_largest_nat_with_property_bounded (P a) (bound a))) indices = None ↔ (∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)find_first_indexed_largest_nat_with_propery_bounded_clause_2 (@find_first_indexed_largest_nat_with_propery_bounded) index P RelDecision0 bound a (inspect (find_largest_nat_with_property_bounded (P a) (bound a))) indices = None ↔ (∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = None → ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
n: nat
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Some n(∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None) → Some (a, n) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = None(∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None) → find_first_indexed_largest_nat_with_propery_bounded P bound indices = Noneby intros Hnone i Hi; apply elem_of_cons in Hi as [-> | Hi]; [| eapply IHindices].index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = None → ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
n: nat
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Some n(∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None) → Some (a, n) = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
n: nat
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Some n
Hmin: ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = NoneSome (a, n) = Noneby symmetry; apply Hmin; left.index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
n: nat
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = Some n
Hmin: ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = NoneNone = find_largest_nat_with_property_bounded (P a) (bound a)index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = None(∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None) → find_first_indexed_largest_nat_with_propery_bounded P bound indices = Noneindex: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hmin: ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = Nonefind_first_indexed_largest_nat_with_propery_bounded P bound indices = Noneby intros; apply Hmin; right. Qed.index: Type
P: index → nat → Prop
RelDecision0: RelDecision P
bound: index → nat
a: index
indices: list index
Ha: a ∉ indices
Hindices: NoDup indices
IHindices: NoDup indices → find_first_indexed_largest_nat_with_propery_bounded P bound indices = None ↔ (∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None)
Hp: find_largest_nat_with_property_bounded (P a) (bound a) = None
Hmin: ∀ i : index, i ∈ a :: indices → find_largest_nat_with_property_bounded (P i) (bound i) = None∀ i : index, i ∈ indices → find_largest_nat_with_property_bounded (P i) (bound i) = None
Section sec_prod_powers. Context `{EqDecision index} `(multipliers : index -> Z) .
Despite being functions,
multipliers
are supposed to represent a list
[m_1, ..., m_n]
and powers
are supposed to represent a list
[p_1, ..., p_n]
. The function computes m_1^p_1 * ... * m_n^p_n
.
Definition prod_powers_aux (powers : index -> nat) (l : list index) : Z := foldr Z.mul 1%Z (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ powers) l)).index: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (eq ==> Permutation ==> eq) prod_powers_auxindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (eq ==> Permutation ==> eq) prod_powers_auxindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat(Permutation ==> eq)%signature (prod_powers_aux f) (prod_powers_aux f)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
x: index
l, l': list index
H: l ≡ₚ l'
IHPermutation: prod_powers_aux f l = prod_powers_aux f l'(multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l)))%Z = (multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l') (map (Z.of_nat ∘ f) l')))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
x, y: index
l: list index(multipliers y ^ Z.of_nat (f y) * (multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Z = (multipliers x ^ Z.of_nat (f x) * (multipliers y ^ Z.of_nat (f y) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
l, l', l'': list index
H: l ≡ₚ l'
H0: l' ≡ₚ l''
IHPermutation1: prod_powers_aux f l = prod_powers_aux f l'
IHPermutation2: prod_powers_aux f l' = prod_powers_aux f l''prod_powers_aux f l = prod_powers_aux f l''by setoid_rewrite IHPermutation.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
x: index
l, l': list index
H: l ≡ₚ l'
IHPermutation: prod_powers_aux f l = prod_powers_aux f l'(multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l)))%Z = (multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l') (map (Z.of_nat ∘ f) l')))%Zby lia.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
x, y: index
l: list index(multipliers y ^ Z.of_nat (f y) * (multipliers x ^ Z.of_nat (f x) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Z = (multipliers x ^ Z.of_nat (f x) * (multipliers y ^ Z.of_nat (f y) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zby congruence. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: index → nat
l, l', l'': list index
H: l ≡ₚ l'
H0: l' ≡ₚ l''
IHPermutation1: prod_powers_aux f l = prod_powers_aux f l'
IHPermutation2: prod_powers_aux f l' = prod_powers_aux f l''prod_powers_aux f l = prod_powers_aux f l''index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers1, powers2: index → nat
l: list index(∀ i : index, i ∈ l → powers1 i = powers2 i) → prod_powers_aux powers1 l = prod_powers_aux powers2 lindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers1, powers2: index → nat
l: list index(∀ i : index, i ∈ l → powers1 i = powers2 i) → prod_powers_aux powers1 l = prod_powers_aux powers2 lindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers1, powers2: index → nat
l: list index
Hall: ∀ i : index, i ∈ l → powers1 i = powers2 ifoldr Z.mul 1%Z (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ powers1) l)) = foldr Z.mul 1%Z (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ powers2) l))index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers1, powers2: index → nat
l: list index
Hall: ∀ i : index, i ∈ l → powers1 i = powers2 imap (Z.of_nat ∘ powers1) l = map (Z.of_nat ∘ powers2) lby intros; cbn; f_equal; apply Hall. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers1, powers2: index → nat
l: list index
Hall: ∀ i : index, i ∈ l → powers1 i = powers2 i∀ x : index, x ∈ l → (Z.of_nat ∘ powers1) x = (Z.of_nat ∘ powers2) xindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
l: list index
Hmpos: Forall (λ i : index, (multipliers i > 0)%Z) l(prod_powers_aux powers l >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
l: list index
Hmpos: Forall (λ i : index, (multipliers i > 0)%Z) l(prod_powers_aux powers l >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
IHl: Forall (λ i : index, (multipliers i > 0)%Z) l → (prod_powers_aux powers l >= 1)%ZForall (λ i : index, (multipliers i > 0)%Z) (a :: l) → (prod_powers_aux powers (a :: l) >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
IHl: Forall (λ i : index, (multipliers i > 0)%Z) l → (prod_powers_aux powers l >= 1)%Z
Hma: (multipliers a > 0)%Z
Hmpos: Forall (λ i : index, (multipliers i > 0)%Z) l(prod_powers_aux powers (a :: l) >= 1)%Zby specialize (IHl Hmpos); lia. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
IHl: Forall (λ i : index, (multipliers i > 0)%Z) l → (prod_powers_aux powers l >= 1)%Z
Hma: (multipliers a > 0)%Z
Hmpos: Forall (λ i : index, (multipliers i > 0)%Z) l(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
l: list index
n: Z
Hn: (n >= 0)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) lExists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
l: list index
n: Z
Hn: (n >= 0)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) lExists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%ZForall (λ i : index, (multipliers i > n)%Z) (a :: l) → Exists (λ i : index, powers i ≠ 0) (a :: l) → (prod_powers_aux powers (a :: l) > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%ZForall (λ i : index, (multipliers i > n)%Z) (a :: l) → Exists (λ i : index, powers i ≠ 0) (a :: l) → (multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
e: powers a = 0(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: powers a ≠ 0(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
e: powers a = 0(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
e: powers a = 0(prod_powers_aux powers l > n)%Zby destruct Hppos.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
e: powers a = 0Exists (λ i : index, powers i ≠ 0) lindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
Hppos: powers a ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: powers a ≠ 0(multipliers a ^ Z.of_nat (powers a) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0(multipliers a ^ Z.of_nat (S pa) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0(multipliers a ^ Z.succ (Z.of_nat pa) * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0(multipliers a * multipliers a ^ Z.of_nat pa * prod_powers_aux powers l > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0(multipliers a ^ Z.of_nat pa * prod_powers_aux powers l >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0(prod_powers_aux powers l >= 1)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: Forall (λ i : index, (multipliers i > n)%Z) l
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0Forall (λ i : index, (multipliers i > 0)%Z) lby intros x Hx; specialize (Hmpos x Hx); lia. Qed. Definition fsfun_prod (f : fsfun index 0) : Z := prod_powers_aux f (fin_supp f).index: Type
EqDecision0: EqDecision index
multipliers: index → Z
powers: index → nat
a: index
l: list index
n: Z
Hn: (n >= 0)%Z
IHl: Forall (λ i : index, (multipliers i > n)%Z) l → Exists (λ i : index, powers i ≠ 0) l → (prod_powers_aux powers l > n)%Z
Hma: (multipliers a > n)%Z
Hmpos: ∀ x : index, x ∈ l → (multipliers x > n)%Z
pa: nat
Hppos: S pa ≠ 0 ∨ Exists (λ i : index, powers i ≠ 0) l
n0: S pa ≠ 0∀ x : index, x ∈ l → (multipliers x > 0)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> eq) fsfun_prodby intros f g Heq; apply prod_powers_aux_proper, fin_supp_proper. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> eq) fsfun_prodindex: Type
EqDecision0: EqDecision index
multipliers: index → Zfsfun_prod zero_fsfun = 1%Zdone. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Zfsfun_prod zero_fsfun = 1%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: indexfsfun_prod (succ_fsfun f n) = (multipliers n * fsfun_prod f)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: indexfsfun_prod (succ_fsfun f n) = (multipliers n * fsfun_prod f)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: indexprod_powers_aux (succ_fsfun f n) (fin_supp (succ_fsfun f n)) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
e: n ∈ fin_supp fprod_powers_aux (succ_fsfun f n) (fin_supp (succ_fsfun f n)) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp fprod_powers_aux (succ_fsfun f n) (fin_supp (succ_fsfun f n)) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
e: n ∈ fin_supp fprod_powers_aux (succ_fsfun f n) (fin_supp (succ_fsfun f n)) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
e: n ∈ fin_supp fprod_powers_aux (succ_fsfun f n) (fin_supp f) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: indexNoDup (fin_supp f) → n ∈ fin_supp f → prod_powers_aux (succ_fsfun f n) (fin_supp f) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%ZNoDup (a :: l) → n ∈ a :: l → prod_powers_aux (succ_fsfun f n) (a :: l) = (multipliers n * prod_powers_aux f (a :: l))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z(a ∉ l) ∧ NoDup l → n = a ∨ n ∈ l → (multipliers a ^ Z.of_nat (succ_fsfun f n a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: n ∉ l
Hnodup: NoDup l(multipliers n ^ Z.of_nat (succ_fsfun f n n) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers n ^ Z.of_nat (f n) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: a ∉ l
Hnodup: NoDup l
Hn: n ∈ l(multipliers a ^ Z.of_nat (succ_fsfun f n a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: n ∉ l
Hnodup: NoDup l(multipliers n ^ Z.of_nat (succ_fsfun f n n) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers n ^ Z.of_nat (f n) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: n ∉ l
Hnodup: NoDup l(multipliers n ^ Z.of_nat (S (f n)) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * multipliers n ^ Z.of_nat (f n) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l)))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: n ∉ l
Hnodup: NoDup lfoldr Z.mul 1%Z (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)) = foldr Z.mul 1%Z (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))by intros; rewrite succ_fsfun_neq; [ |set_solver].index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: n ∉ l
Hnodup: NoDup l∀ i : index, i ∈ l → succ_fsfun f n i = f iindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: a ∉ l
Hnodup: NoDup l
Hn: n ∈ l(multipliers a ^ Z.of_nat (succ_fsfun f n a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: a ∉ l
Hnodup: NoDup l
Hn: n ∈ l(multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ succ_fsfun f n) l)))%Z = (multipliers n * (multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zby unfold prod_powers_aux; lia.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n, a: index
l: list index
IHl: NoDup l → n ∈ l → prod_powers_aux (succ_fsfun f n) l = (multipliers n * prod_powers_aux f l)%Z
Ha: a ∉ l
Hnodup: NoDup l
Hn: n ∈ l(multipliers a ^ Z.of_nat (f a) * (multipliers n * prod_powers_aux f l))%Z = (multipliers n * (multipliers a ^ Z.of_nat (f a) * foldr Z.mul 1 (zip_with Z.pow (map multipliers l) (map (Z.of_nat ∘ f) l))))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp fprod_powers_aux (succ_fsfun f n) (fin_supp (succ_fsfun f n)) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp fprod_powers_aux (succ_fsfun f n) (n :: fin_supp f) = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp f(multipliers n ^ Z.of_nat (S (f n)) * foldr Z.mul 1 (zip_with Z.pow (map multipliers (fin_supp f)) (map (Z.of_nat ∘ succ_fsfun f n) (fin_supp f))))%Z = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp f(multipliers n ^ Z.of_nat 1 * foldr Z.mul 1 (zip_with Z.pow (map multipliers (fin_supp f)) (map (Z.of_nat ∘ succ_fsfun f n) (fin_supp f))))%Z = (multipliers n * prod_powers_aux f (fin_supp f))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp ffoldr Z.mul 1%Z (zip_with Z.pow (map multipliers (fin_supp f)) (map (Z.of_nat ∘ succ_fsfun f n) (fin_supp f))) = prod_powers_aux f (fin_supp f)by intros; rewrite succ_fsfun_neq; [| set_solver]. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f: fsfun index 0
n: index
n0: n ∉ fin_supp f∀ i : index, i ∈ fin_supp f → succ_fsfun f n i = f iindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: indexfsfun_prod (delta_nat_fsfun n) = multipliers nindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: indexfsfun_prod (delta_nat_fsfun n) = multipliers nindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: indexfsfun_prod (succ_fsfun zero_fsfun n) = multipliers nby lia. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: index(multipliers n * 1)%Z = multipliers nindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z∀ f : fsfun index 0, fin_supp f ≠ [] → (fsfun_prod f > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z∀ f : fsfun index 0, fin_supp f ≠ [] → (fsfun_prod f > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ [](fsfun_prod f > n)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []Forall (λ i : index, (multipliers i > n)%Z) (fin_supp f)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []Exists (λ i : index, f i ≠ 0) (fin_supp f)by apply Forall_forall; intros; apply Hmpos.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []Forall (λ i : index, (multipliers i > n)%Z) (fin_supp f)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []Exists (λ i : index, f i ≠ 0) (fin_supp f)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []∃ x : index, x ∈ fin_supp f ∧ f x ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
H: fin_supp f ≠ []∃ x : index, (∃ y : {x0 : index | bool_decide (f x0 ≠ 0)}, x = `y ∧ y ∈ enum (support 0 f)) ∧ f x ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
i: index
l: list index
Heq: fin_supp f = i :: l
H: i :: l ≠ []∃ x : index, (∃ y : {x0 : index | bool_decide (f x0 ≠ 0)}, x = `y ∧ y ∈ enum (support 0 f)) ∧ f x ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
i: index
l: list index
Heq: fin_supp f = i :: l
H: i :: l ≠ []
Hi: i ∈ fin_supp f∃ x : index, (∃ y : {x0 : index | bool_decide (f x0 ≠ 0)}, x = `y ∧ y ∈ enum (support 0 f)) ∧ f x ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
i: index
l: list index
Heq: fin_supp f = i :: l
H: i :: l ≠ []
Hi: ∃ y : {x : index | bool_decide (f x ≠ 0)}, i = `y ∧ y ∈ enum (support 0 f)∃ x : index, (∃ y : {x0 : index | bool_decide (f x0 ≠ 0)}, x = `y ∧ y ∈ enum (support 0 f)) ∧ f x ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
i: index
l: list index
Heq: fin_supp f = i :: l
H: i :: l ≠ []
Hi: ∃ y : {x : index | bool_decide (f x ≠ 0)}, i = `y ∧ y ∈ enum (support 0 f)f i ≠ 0by eapply bool_decide_unpack. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
n: Z
Hn: (n >= 0)%Z
Hmpos: ∀ i : index, (multipliers i > n)%Z
f: fsfun index 0
l: list index
j: index
H: j :: l ≠ []
Heq: fin_supp f = j :: l
Hj: bool_decide (f j ≠ 0)
b: j ↾ Hj ∈ enum (support 0 f)f j ≠ 0index: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (f : fsfun index 0) (i : index), i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (f : fsfun index 0) (i : index), i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> impl) (λ f : fsfun index 0, ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z)index: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ i : index, i ∈ fin_supp zero_fsfun → (multipliers i | fsfun_prod zero_fsfun)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (i : index) (f : fsfun index 0), (∀ i0 : index, i0 ∈ fin_supp f → (multipliers i0 | fsfun_prod f)%Z) → ∀ i0 : index, i0 ∈ fin_supp (succ_fsfun f i) → (multipliers i0 | fsfun_prod (succ_fsfun f i))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> impl) (λ f : fsfun index 0, ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f, g: fsfun index 0
Heq: f ≡ g
Hall: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp g(multipliers i | fsfun_prod g)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f, g: fsfun index 0
Heq: f ≡ g
Hall: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp f(multipliers i | fsfun_prod g)%Zby exists x; rewrite <- Heq.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f, g: fsfun index 0
Heq: f ≡ g
Hall: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
x: Z
Hx: fsfun_prod f = (x * multipliers i)%Z(multipliers i | fsfun_prod g)%Zby inversion 1.index: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ i : index, i ∈ fin_supp zero_fsfun → (multipliers i | fsfun_prod zero_fsfun)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (i : index) (f : fsfun index 0), (∀ i0 : index, i0 ∈ fin_supp f → (multipliers i0 | fsfun_prod f)%Z) → ∀ i0 : index, i0 ∈ fin_supp (succ_fsfun f i) → (multipliers i0 | fsfun_prod (succ_fsfun f i))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
j: index
f: fsfun index 0
IHf: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp (succ_fsfun f j)(multipliers i | fsfun_prod (succ_fsfun f j))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
j: index
f: fsfun index 0
IHf: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp (succ_fsfun f j)(multipliers i | multipliers j * fsfun_prod f)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
j: index
f: fsfun index 0
IHf: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp f(multipliers i | multipliers j * fsfun_prod f)%Zby exists (multipliers j * x)%Z; lia. Qed.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
j: index
f: fsfun index 0
IHf: ∀ i : index, i ∈ fin_supp f → (multipliers i | fsfun_prod f)%Z
i: index
Hi: i ∈ fin_supp f
x: Z(multipliers i | multipliers j * (x * multipliers i))%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ f1 f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ f1 f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> impl) (λ f1 : fsfun index 0, ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Z)index: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ f2 : fsfun index 0, fsfun_prod (add_fsfun zero_fsfun f2) = (fsfun_prod zero_fsfun * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (i : index) (f : fsfun index 0), (∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f f2) = (fsfun_prod f * fsfun_prod f2)%Z) → ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun (succ_fsfun f i) f2) = (fsfun_prod (succ_fsfun f i) * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → ZProper (equiv ==> impl) (λ f1 : fsfun index 0, ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Z)index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f, f1: fsfun index 0
Heq: f ≡ f1
Hall: ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f f2) = (fsfun_prod f * fsfun_prod f2)%Z
f2: fsfun index 0fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Zby lia.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f, f1: fsfun index 0
Heq: f ≡ f1
Hall: ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f f2) = (fsfun_prod f * fsfun_prod f2)%Z
f2: fsfun index 0(fsfun_prod f * fsfun_prod f2)%Z = (fsfun_prod f * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ f2 : fsfun index 0, fsfun_prod (add_fsfun zero_fsfun f2) = (fsfun_prod zero_fsfun * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
f2: fsfun index 0fsfun_prod (add_fsfun zero_fsfun f2) = (fsfun_prod zero_fsfun * fsfun_prod f2)%Zby lia.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
f2: fsfun index 0fsfun_prod f2 = (1 * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z∀ (i : index) (f : fsfun index 0), (∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f f2) = (fsfun_prod f * fsfun_prod f2)%Z) → ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun (succ_fsfun f i) f2) = (fsfun_prod (succ_fsfun f i) * fsfun_prod f2)%Zindex: Type
EqDecision0: EqDecision index
multipliers: index → Z
i: index
f1: fsfun index 0
Hall: ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Z
f2: fsfun index 0fsfun_prod (add_fsfun (succ_fsfun f1 i) f2) = (fsfun_prod (succ_fsfun f1 i) * fsfun_prod f2)%Zby lia. Qed. End sec_prod_powers.index: Type
EqDecision0: EqDecision index
multipliers: index → Z
i: index
f1: fsfun index 0
Hall: ∀ f2 : fsfun index 0, fsfun_prod (add_fsfun f1 f2) = (fsfun_prod f1 * fsfun_prod f2)%Z
f2: fsfun index 0(multipliers i * (fsfun_prod f1 * fsfun_prod f2))%Z = (multipliers i * fsfun_prod f1 * fsfun_prod f2)%Z
#[export] Instance prime_decision : forall n, Decision (prime n) := prime_dec.
The type of prime numbers.
Definition primes : Type := dsig prime. #[export] Program Instance primes_inhabited : Inhabited primes := populate (dexist 2%Z prime_2).
Compute the product of powers of primes represented by
powers
.
Since there are only finitely many of them, the result is well-defined.
Definition prod_primes_powers (powers : fsfun primes 0) : Z := fsfun_prod (fun p : primes => ` p) powers.∀ n : Z, (n > 1)%Z → ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)∀ n : Z, (n > 1)%Z → ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)P:= λ n : Z, ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z): Z → Prop∀ n : Z, (n > 1)%Z → ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)P:= λ n : Z, ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z): Z → Prop(∀ n : Z, (2 ≤ n)%Z → P n) → ∀ n : Z, (n > 1)%Z → ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)P:= λ n : Z, ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z): Z → Prop∀ n : Z, (2 ≤ n)%Z → P nby intros HP n Hn1 Hnp; apply HP; [lia |].P:= λ n : Z, ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z): Z → Prop(∀ n : Z, (2 ≤ n)%Z → P n) → ∀ n : Z, (n > 1)%Z → ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)P:= λ n : Z, ¬ prime n → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z): Z → Prop∀ n : Z, (2 ≤ n)%Z → P nn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hn2: (2 ≤ n)%Z
Hnp: ¬ prime n∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < n)%Z ∧ n = (q * m)%Z)p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z∃ m : Z, prime m ∧ (∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * m)%Z)p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
p0: prime p∃ m : Z, prime m ∧ (∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * m)%Z)p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
Hnp: ¬ prime p∃ m : Z, prime m ∧ (∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * m)%Z)p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
p0: prime p∃ m : Z, prime m ∧ (∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * m)%Z)p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
p0: prime p∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * p)%Zby nia.p, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
p0: prime p(2 ≤ q < q * p)%Zp, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
Hnp: ¬ prime p∃ m : Z, prime m ∧ (∃ q0 : Z, (2 ≤ q0 < q * p)%Z ∧ (q * p)%Z = (q0 * m)%Z)q, m, q': Z
Hq': (2 ≤ q' < q' * m)%Z
Hpn: (q' * m < q * (q' * m))%Z
Hp1: (1 < q' * m)%Z
Hind: ∀ y : Z, (2 ≤ y < q * (q' * m))%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hn2: (2 ≤ q * (q' * m))%Z
Hmprime: prime m∃ m0 : Z, prime m0 ∧ (∃ q0 : Z, (2 ≤ q0 < q * (q' * m))%Z ∧ (q * (q' * m))%Z = (q0 * m0)%Z)by exists (q * q')%Z; split; nia. Qed.q, m, q': Z
Hq': (2 ≤ q' < q' * m)%Z
Hpn: (q' * m < q * (q' * m))%Z
Hp1: (1 < q' * m)%Z
Hind: ∀ y : Z, (2 ≤ y < q * (q' * m))%Z → ¬ prime y → ∃ m : Z, prime m ∧ (∃ q : Z, (2 ≤ q < y)%Z ∧ y = (q * m)%Z)
Hn2: (2 ≤ q * (q' * m))%Z
Hmprime: prime m∃ q0 : Z, (2 ≤ q0 < q * (q' * m))%Z ∧ (q * (q' * m))%Z = (q0 * m)%Z∀ n : Z, (n > 1)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers ps∀ n : Z, (n > 1)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
H_n: (n > 1)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hn: (2 ≤ n)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
p: prime n∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
Hnp: ¬ prime n∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
p: prime n∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psn: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
p: prime nfin_supp (delta_nat_fsfun (dexist n p)) ≠ [] ∧ n = prod_primes_powers (delta_nat_fsfun (dexist n p))by eapply elem_of_not_nil, elem_of_delta_nat_fsfun.n: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
p: prime nfin_supp (delta_nat_fsfun (dexist n p)) ≠ []n: Z
Hind: ∀ y : Z, (2 ≤ y < n)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ n)%Z
Hnp: ¬ prime n∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ n = prod_primes_powers psp, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ (q * p)%Z = prod_primes_powers psp, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
Hq1: (1 < q)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ (q * p)%Z = prod_primes_powers psp, q: Z
Hn2: (2 ≤ q * p)%Z
Hind: ∀ y : Z, (2 ≤ y < q * p)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hp1: (1 < p)%Z
Hpn: (p < q * p)%Z
Hq1: (1 < q)%Z
Hqn: (q < q * p)%Z∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ (q * p)%Z = prod_primes_powers psq: Z
ps: fsfun primes 0
Hpn: (prod_primes_powers ps < q * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < q * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hn2: (2 ≤ q * prod_primes_powers ps)%Z
Hq1: (1 < q)%Z
Hqn: (q < q * prod_primes_powers ps)%Z
Hdomps: fin_supp ps ≠ []∃ ps0 : fsfun primes 0, fin_supp ps0 ≠ [] ∧ (q * prod_primes_powers ps)%Z = prod_primes_powers ps0ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ []∃ ps0 : fsfun primes 0, fin_supp ps0 ≠ [] ∧ (prod_primes_powers qs * prod_primes_powers ps)%Z = prod_primes_powers ps0ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ []fin_supp (add_fsfun qs ps) ≠ [] ∧ (prod_primes_powers qs * prod_primes_powers ps)%Z = prod_primes_powers (add_fsfun qs ps)ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ []fin_supp (add_fsfun qs ps) ≠ []ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ [](prod_primes_powers qs * prod_primes_powers ps)%Z = prod_primes_powers (add_fsfun qs ps)ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ []fin_supp (add_fsfun qs ps) ≠ []ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: dsig (λ i : primes, i ∈ fin_supp ps)
Hdomqs: fin_supp qs ≠ []fin_supp (add_fsfun qs ps) ≠ []by eapply elem_of_not_nil, elem_of_add_fsfun; right.ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: dsig (λ i : primes, i ∈ fin_supp ps)
Hdomqs: fin_supp qs ≠ []
i: primes
Hi: i ∈ fin_supp ps
Heq: Hdomps = dexist i Hifin_supp (add_fsfun qs ps) ≠ []by symmetry; apply prod_powers_add. Qed.ps, qs: fsfun primes 0
Hpn: (prod_primes_powers ps < prod_primes_powers qs * prod_primes_powers ps)%Z
Hp1: (1 < prod_primes_powers ps)%Z
Hqn: (prod_primes_powers qs < prod_primes_powers qs * prod_primes_powers ps)%Z
Hq1: (1 < prod_primes_powers qs)%Z
Hn2: (2 ≤ prod_primes_powers qs * prod_primes_powers ps)%Z
Hind: ∀ y : Z, (2 ≤ y < prod_primes_powers qs * prod_primes_powers ps)%Z → ∃ ps : fsfun primes 0, fin_supp ps ≠ [] ∧ y = prod_primes_powers ps
Hdomps: fin_supp ps ≠ []
Hdomqs: fin_supp qs ≠ [](prod_primes_powers qs * prod_primes_powers ps)%Z = prod_primes_powers (add_fsfun qs ps)