Built with Alectryon, running Coq+SerAPI v8.20.0+0.20.0. Bubbles () indicate interactive fragments: hover for details, tap to reveal contents. Use Ctrl+↑Ctrl+↓ to navigate, Ctrl+🖱️ to focus. On Mac, use ⌘ instead of Ctrl.
[Loading ML file ssrmatching_plugin.cmxs (using legacy method) ... done]
[Loading ML file ssreflect_plugin.cmxs (using legacy method) ... done]
[Loading ML file ring_plugin.cmxs (using legacy method) ... done]
Serlib plugin: coq-elpi.elpi is not available: serlib support is missing.
Incremental checking for commands in this plugin will be impacted.
[Loading ML file coq-elpi.elpi ... done]
Notation"_ + _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ - _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ < _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ >= _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ > _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Notation"_ <= _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ <= _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ <= _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ < _ < _" was already used in scope
nat_scope. [notation-overridden,parsing,default]
Notation"_ * _" was already used in scope nat_scope.
[notation-overridden,parsing,default]
Require Export prosa.util.rel.
[Loading ML file zify_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_core_plugin.cmxs (using legacy method) ... done]
[Loading ML file micromega_plugin.cmxs (using legacy method) ... done]
[Loading ML file btauto_plugin.cmxs (using legacy method) ... done]
Require Export prosa.util.minmax.(** * Fixpoint Search *)(** This module provides some utilities for finding positive fixpoints of monotonic functions. *)(** ** Least Positive Fixpoint *)(** Finds the least fixpoint of a monotonic function, between a start point [s] and a horizon [h], given an amount of [fuel]. *)Fixpointfind_fixpoint_from (f : nat -> nat) (xhfuel: nat): option nat :=
if fuel is S fuel' thenif f x == x then
Some x
elseif (f x) <= h then
find_fixpoint_from f (f x) h fuel'
else None
else None.(** Given a horizon [h] and a monotonic function [f], find the least positive fixpoint of [f] no larger than [h], if any. *)Definitionfind_fixpoint (f : nat -> nat) (h : nat) : option nat :=
find_fixpoint_from f 1 h h.(** In the following, we show that the fixpoint search works as expected. *)SectionFixpointSearch.(** Consider any function [f] ... *)Variablef : nat -> nat.(** ... and any given horizon. *)Variableh : nat.(** We show that the result of [find_fixpoint_from] is indeed a fixpoint. *)
f: nat -> nat h: nat
forallsxfuel : nat,
find_fixpoint_from f s h fuel = Some x -> x = f x
f: nat -> nat h: nat
forallsxfuel : nat,
find_fixpoint_from f s h fuel = Some x -> x = f x
f: nat -> nat h, s, x, fuel: nat
find_fixpoint_from f s h fuel = Some x -> x = f x
f: nat -> nat h, x, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some x ->
x = f x s': nat
find_fixpoint_from f s' h fuel'.+1 = Some x -> x = f x
f: nat -> nat h, x, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some x ->
x = f x s': nat
(if f s' == s'
then Some s'
elseif f s' <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s') h fuel'
else None) = Some x -> x = f x
f: nat -> nat h, x, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some x ->
x = f x s': nat
(if f s' <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s') h fuel'
else None) = Some x -> x = f x
f: nat -> nat h, x, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some x ->
x = f x s': nat
(if f s' <= h
then find_fixpoint_from f (f s') h fuel'
else None) = Some x -> x = f x
bycase: (f s' <= h).Qed.(** Using the above fact, we observe that the result of [find_fixpoint] is a fixpoint. *)
f: nat -> nat h: nat
forallx : nat, find_fixpoint f h = Some x -> x = f x
f: nat -> nat h: nat
forallx : nat, find_fixpoint f h = Some x -> x = f x
bymove=> x FOUND; apply: ffpf_finds_fixpoint FOUND.Qed.(** Next, we establish properties that rely on the monotonic properties of the function. *)SectionMonotonicFunction.(** Suppose [f] is monotonically increasing ... *)HypothesisH_f_mono: monotone leq f.(** ... and not zero at 1. *)HypothesisF1: f 1 > 0.(** Assuming the function is monotonic, there is no fixpoint between [a] and [c], if [f a = c]. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallac : nat,
c = f a -> forallb : nat, a <= b < c -> b != f b
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallac : nat,
c = f a -> forallb : nat, a <= b < c -> b != f b
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 a, c: nat EQ: c = f a b: nat LEQ: a <= b LT: b < c
b != f b
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 a, c: nat EQ: c = f a b: nat LEQ: a <= b LT: b < c MONO: f a <= f b
b != f b
bylia.Qed.(** It follows that [find_fixpoint_from] finds the least fixpoint larger than [s]. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallysfuel : nat,
find_fixpoint_from f s h fuel = Some y ->
forallx : nat, s <= x < y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallysfuel : nat,
find_fixpoint_from f s h fuel = Some y ->
forallx : nat, s <= x < y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, s, fuel: nat
find_fixpoint_from f s h fuel = Some y ->
forallx : nat, s <= x < y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s: nat FFP: find_fixpoint_from f s h fuel'.+1 = Some y x: nat LEQx: s <= x LT: x < y
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y
(if f s == s
then Some s
elseif f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) = Some y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y
f s != s ->
(if f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) = Some y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s
(if f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) = Some y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' = Some y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y fsLEQs: f s <= x
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y sLTfs: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y fsLEQs: f s <= x
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y fsLEQs: f s <= x
f s <= x < y
byapply /andP; split.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y sLTfs: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y sLTfs: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 y, fuel': nat IH: foralls : nat,
find_fixpoint_from f s h fuel' = Some y ->
forallx : nat, s <= x < y -> x != f x s, x: nat LEQx: s <= x LT: x < y EQ: f s != s LEQh: f s <= h FFP: find_fixpoint_from f (f s) h fuel' = Some y sLTfs: x < f s
s <= x < f s
byapply /andP; split.}Qed.(** Hence [find_fixpoint] finds the least positive fixpoint of [f]. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallxy : nat,
0 < x < y -> find_fixpoint f h = Some y -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallxy : nat,
0 < x < y -> find_fixpoint f h = Some y -> x != f x
bymove=> x y LT FFP; apply: ffpf_finds_least_fixpoint; eauto.Qed.(** Furthermore, we observe that [find_fixpoint_from] finds positive fixpoints when provided with a positive starting point [s]. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallsfuelx : nat,
Some x = find_fixpoint_from f s h fuel ->
0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallsfuelx : nat,
Some x = find_fixpoint_from f s h fuel ->
0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 s, fuel, x: nat
Some x = find_fixpoint_from f s h fuel ->
0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 s, fuel, x: nat
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel -> 0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat
Some x =
(if f s == s
then Some s
elseif f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) -> 0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat SOME: Some x = Some s
0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s
Some x =
(if f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) -> 0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat SOME: Some x = Some s
0 < s -> 0 < x
bymove: SOME => []; lia.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s
Some x =
(if f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) -> 0 < s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s SOME: Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' GT: 0 < s
0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s SOME: Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' GT: 0 < s
0 < f s
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s SOME: Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' GT: 0 < s
0 < f s -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s SOME: Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' GT: 0 < s
0 < f s
bymove: (H_f_mono 1 s GT) => MONO; lia.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x, fuel': nat IH: foralls : nat,
Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f s h fuel' ->
0 < s -> 0 < x s: nat NEQ: f s != s SOME: Some x =
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct
fuel} : option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' GT: 0 < s
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallx : nat, Some x = find_fixpoint f h -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallx : nat, Some x = find_fixpoint f h -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x: nat
Some x = find_fixpoint f h -> 0 < x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 x: nat FIX: Some x = find_fixpoint_from f 1 h h
0 < x
byapply: ffpf_finds_positive_fixpoint; firstapply FIX.Qed.(** If [find_fixpoint_from] finds no fixpoint between s and h, there is none. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallsfuel : nat,
s <= f s ->
h - s <= fuel ->
find_fixpoint_from f s h fuel = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
forallsfuel : nat,
s <= f s ->
h - s <= fuel ->
find_fixpoint_from f s h fuel = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 s, fuel: nat
s <= f s ->
h - s <= fuel ->
find_fixpoint_from f s h fuel = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1
find_fixpoint_from f s h fuel'.+1 = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1
(if f s == s
then Some s
elseif f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s
(if f s <= h
then
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel'
else None) = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s GTNh: h < f s
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s GTNh: h < f s
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s GTNh: h < f s x: nat SX: s <= x LT: x < h
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s GTNh: h < f s x: nat SX: s <= x LT: x < h
s <= x < f s
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s GTNh: h < f s x: nat SX: s <= x LT: x < h
x < f s
byapply: ltn_trans LT GTNh.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s
(fix find_fixpoint_from
(f : nat -> nat) (x h fuel : nat) {struct fuel} :
option nat :=
match fuel with
| 0 => None
| fuel'.+1 =>
if f x == x
then Some x
elseif f x <= h
then find_fixpoint_from f (f x) h fuel'
else None
end) f (f s) h fuel' = None ->
forallx : nat, s <= x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
h - f s <= fuel'
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
f s <= x < h
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
h - f s <= fuel'
bylia.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: f s <= x
f s <= x < h
byapply /andP; split.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: x < f s
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 fuel': nat IH: foralls : nat,
s <= f s ->
h - s <= fuel' ->
find_fixpoint_from f s h fuel' = None ->
forallx : nat, s <= x < h -> x != f x s: nat GEQ: s <= f s FUEL: h - s <= fuel'.+1 F: f s != s FFP: find_fixpoint_from f (f s) h fuel' = None x: nat SX: s <= x XH: x < h FSX: x < f s
s <= x < f s
byapply /andP; split.}}Qed.(** Hence, if [find_fixpoint] finds no positive fixpoint less than h, there is none. *)
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
find_fixpoint f h = None ->
forallx : nat, 0 < x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1
find_fixpoint f h = None ->
forallx : nat, 0 < x < h -> x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
x != f x
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
0 < f 1
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
h - 1 <= h
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
find_fixpoint_from f 1 h h = None
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
0 < x < h
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
0 < f 1
bymove: F1; case (f 1) => //.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
h - 1 <= h
byrewrite subn1; exact /leq_pred.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
find_fixpoint_from f 1 h h = None
byexact: FFP.
f: nat -> nat h: nat H_f_mono: monotone leq f F1: 0 < f 1 FFP: find_fixpoint f h = None x: nat POS: 0 < x LT: x < h
0 < x < h
byapply /andP; split.Qed.EndMonotonicFunction.EndFixpointSearch.(** ** Maximal Fixpoint across a Search Space *)(** Given a function taking two inputs and a search space for the first argument, [find_max_fixpoint_of_seq] finds the maximum fixpoint with regard to the second argument across the search space, but only if a fixpoint exists for each point in the search space. *)Definitionfind_max_fixpoint_of_seq (f : nat -> nat -> nat)
(sp : seq nat) (h : nat) : option nat :=
letis_someopt := opt != None inlet fixpoints := [seq find_fixpoint (f s) h | s <- sp] inletmax := \max_(fp <- fixpoints | is_some fp) (odflt 0) fp inifall is_some fixpoints then Some max else None.(** We prove that the result of the [find_max_fixpoint_of_seq] is a fixpoint of the function for an element of the search space. *)
forall (f : nat -> nat -> nat) (sp : seq nat)
(hx : nat),
~~ nilp sp ->
find_max_fixpoint_of_seq f sp h = Some x ->
exists2 a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
forall (f : nat -> nat -> nat) (sp : seq nat)
(hx : nat),
~~ nilp sp ->
find_max_fixpoint_of_seq f sp h = Some x ->
exists2 a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
(ifall (funopt : option nat => opt != None)
[seq find_fixpoint (f s) h | s <- sp]
then
Some
(\max_(fp <- [seq find_fixpoint (f s) h | s <- sp] |
fp != None) odflt 0 fp)
else None) = Some x ->
exists2 a : nat, a \in sp & x = f a x
f: nat -> nat -> nat sp: seq nat h, x: nat NN: ~~ nilp sp fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) H: (ifall (funopt : option nat => opt != None) fps
then
Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None) = Some x
exists2 a : nat, a \in sp & x = f a x
f: nat -> nat -> nat sp: seq nat h, x: nat NN: ~~ nilp sp fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) H: (ifall (funopt : option nat => opt != None) fps
then
Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None) = Some x ALL: all
(funopt : Datatypes_option__canonical__eqtype_Equality
Datatypes_nat__canonical__eqtype_Equality => opt != None) fps
(ifall (funopt : option nat => opt != None) fps
then Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None) = Some x ->
exists2 a : nat, a \in sp & x = f a x
w =
\max_(x <- fps | x != None)
match x with
| Some x' => x'
| None => 0end -> exists2 a : nat, a \in sp & x = f a x
f: nat -> nat -> nat sp: seq nat h, x: nat NN: ~~ nilp sp fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) ALL: all
(funopt : Datatypes_option__canonical__eqtype_Equality
Datatypes_nat__canonical__eqtype_Equality => opt != None) fps NN': ~~ nilp fps w: nat IN: Some w \in fps WX: w = x
exists2 a : nat, a \in sp & x = f a x
f: nat -> nat -> nat sp: seq nat h, x: nat NN: ~~ nilp sp fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) ALL: all
(funopt : Datatypes_option__canonical__eqtype_Equality
Datatypes_nat__canonical__eqtype_Equality => opt != None) fps NN': ~~ nilp fps w: nat WX: w = x a: Datatypes_nat__canonical__eqtype_Equality IN: a \in sp FIX: Some x = find_fixpoint (f a) h
exists2 a : nat, a \in sp & x = f a x
f: nat -> nat -> nat sp: seq nat h, x: nat NN: ~~ nilp sp fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) ALL: all
(funopt : Datatypes_option__canonical__eqtype_Equality
Datatypes_nat__canonical__eqtype_Equality => opt != None) fps NN': ~~ nilp fps w: nat WX: w = x a: Datatypes_nat__canonical__eqtype_Equality IN: a \in sp FIX: Some x = find_fixpoint (f a) h
x = f a x
byeapply ffp_finds_fixpoint, ssrfun.esym, FIX.Qed.(** Furthermore, we show that the result is the maximum of all fixpoints, with regard to the search space.*)
forall (f : nat -> nat -> nat) (sp : seq nat)
(hsr : nat),
Some r = find_max_fixpoint_of_seq f sp h ->
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
forall (f : nat -> nat -> nat) (sp : seq nat)
(hsr : nat),
Some r = find_max_fixpoint_of_seq f sp h ->
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
f: nat -> nat -> nat sp: seq nat h, s, r: nat
Some r = find_max_fixpoint_of_seq f sp h ->
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
f: nat -> nat -> nat sp: seq nat h, s, r: nat
Some r =
(ifall (funopt : option nat => opt != None)
[seq find_fixpoint (f s) h | s <- sp]
then
Some
(\max_(fp <- [seq find_fixpoint (f s) h | s <- sp] |
fp != None) odflt 0 fp)
else None) ->
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
f: nat -> nat -> nat sp: seq nat h, s, r: nat fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) H: Some r =
(ifall (funopt : option nat => opt != None) fps
then
Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None)
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
f: nat -> nat -> nat sp: seq nat h, s, r: nat fps:= [seq find_fixpoint (f s) h | s <- sp]: seq (option nat) H: Some r =
(ifall (funopt : option nat => opt != None) fps
then
Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None) ALL: all
(funopt : Datatypes_option__canonical__eqtype_Equality
Datatypes_nat__canonical__eqtype_Equality => opt != None) fps
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
Some r =
(ifall (funopt : option nat => opt != None) fps
then Some (\max_(fp <- fps | fp != None) odflt 0 fp)
else None) ->
s \in sp ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
all: byrewrite /fps; exact: map_f.Qed.(** ** Search Space Defined by a Predicate *)SectionPredicateSearchSpace.(** Consider a limit [L] ... *)VariableL : nat.(** ... and any predicate [P] on numbers. *)VariableP : pred nat.(** We create a derive predicate that defines the search space as all values less than [L] that satisfy [P]. *)Letis_in_search_spaceA := (A < L) && P A.(** This is used to create a corresponding sequence of points in the search space. *)Letsp := [seq s <- (iota 0 L) | P s].(** Based on this conversion, we define a function to find the maximum of all fixpoints within the search space. *)Definitionfind_max_fixpoint (f : nat -> nat -> nat) (h : nat) :=
if (has P (iota 0 L)) then find_max_fixpoint_of_seq f sp h else None.(** The result of [find_max_fixpoint] is a fixpoint of the function [f] for a an element of the search space. *)
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat
forall (f : nat -> nat -> nat) (hx : nat),
find_max_fixpoint f h = Some x ->
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat
forall (f : nat -> nat -> nat) (hx : nat),
find_max_fixpoint f h = Some x ->
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x
~~ nilp sp
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x
~~ nilp sp
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat
find_max_fixpoint f h = Some x -> ~~ nilp sp
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat
(if0 < count P (iota 0 L)
then
find_max_fixpoint_of_seq f [seq s <- iota 0 L | P s]
h
else None) = Some x -> count [eta P] (iota 0 L) != 0
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat
(if0 < count P (iota 0 L)
then
find_max_fixpoint_of_seq f [seq x <- iota 0 L | P x]
h
else None) = Some x -> count P (iota 0 L) != 0
bycase (count P (iota 0 L)) => //.
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
exists2 a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp FP: exists2
a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
exists2 a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
~~ nilp sp
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
find_max_fixpoint_of_seq f sp ?Goal0 = Some x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
~~ nilp sp
exact: NILP.
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp
find_max_fixpoint_of_seq f sp ?Goal0 = Some x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat NILP: ~~ nilp sp
find_max_fixpoint f h = Some x ->
find_max_fixpoint_of_seq f sp ?Goal0 = Some x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat NILP: ~~ nilp sp
(if has P (iota 0 L)
then find_max_fixpoint_of_seq f sp h
else None) = Some x ->
find_max_fixpoint_of_seq f sp ?Goal0 = Some x
case: (has P (iota 0 L)) => //; exact.
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp FP: exists2
a : Datatypes_nat__canonical__eqtype_Equality,
a \in sp & x = f a x
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp a: Datatypes_nat__canonical__eqtype_Equality IN: a \in sp FP: x = f a x
exists2 a : nat, is_in_search_space a & x = f a x
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, x: nat SOME: find_max_fixpoint f h = Some x NILP: ~~ nilp sp a: Datatypes_nat__canonical__eqtype_Equality IN: a \in sp FP: x = f a x
is_in_search_space a
bymove: IN; rewrite /sp /is_in_search_space mem_filter mem_iota andbC.Qed.(** Finally, we observe that there is no fixpoint in the search space larger than the result of [find_maximum_fixpoint]. *)
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat
forall (f : nat -> nat -> nat) (hsr : nat),
Some r = find_max_fixpoint f h ->
is_in_search_space s ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat
forall (f : nat -> nat -> nat) (hsr : nat),
Some r = find_max_fixpoint f h ->
is_in_search_space s ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, s, r: nat
Some r = find_max_fixpoint f h ->
is_in_search_space s ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, s, r: nat
Some r =
(if has P (iota 0 L)
then find_max_fixpoint_of_seq f sp h
else None) ->
is_in_search_space s ->
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, s, r: nat SOME: Some r = find_max_fixpoint_of_seq f sp h PRED: is_in_search_space s
exists2 v : nat,
Some v = find_fixpoint (f s) h & v <= r
L: nat P: pred nat is_in_search_space:= funA : nat => (A < L) && P A: nat -> bool sp:= [seq s <- iota 0 L | P s]: seq nat f: nat -> nat -> nat h, s, r: nat SOME: Some r = find_max_fixpoint_of_seq f sp h PRED: is_in_search_space s