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]
[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 Import prosa.util.tactics.(** This file introduces a function called [search_arg] that allows finding the argument within a given range for which a function is minimal w.r.t. to a given order while satisfying a given predicate, along with lemmas establishing the basic properties of [search_arg]. Note that while this is quite similar to [arg min ...] / [arg max ...] in [ssreflect] ([fintype]), this function is subtly different in that it possibly returns None and that it does not require the last element in the given range to satisfy the predicate. In contrast, [ssreflect]'s notion of extremum in [fintype] uses the upper bound of the search space as the default value, which is rather unnatural when searching through a schedule.*)(** First, we show that, given an interval <<[t1, t2)>> and a predicate [P], either no element in the interval satisfy [P] or there is an element that satisfies [P]. *)
forall (P : pred nat) (t1t2 : nat),
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
forall (P : pred nat) (t1t2 : nat),
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat ALL: {in index_iota t1 t2,
forallx : Datatypes_nat__canonical__eqtype_Equality, ~~ P x}
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat ALL: {in index_iota t1 t2,
forallx : Datatypes_nat__canonical__eqtype_Equality, ~~ P x}
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
byleft => t IN; apply: ALL; rewrite mem_index_iota.
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x
(forallt : nat, t1 <= t < t2 -> ~~ P t) \/
(existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t'))
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x
existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t')
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x EX: existsn : nat, (t1 <= n < t2) && P n
existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t')
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x EX: existsn : nat, (t1 <= n < t2) && P n x': nat IN': t1 <= x' < t2 Px': P x' MIN: foralln : nat, (t1 <= n < t2) && P n -> x' <= n
existst : nat,
t1 <= t < t2 /\
P t /\
(forallt' : nat, t1 <= t' -> P t' -> t <= t')
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x EX: existsn : nat, (t1 <= n < t2) && P n x': nat IN': t1 <= x' < t2 Px': P x' MIN: foralln : nat, (t1 <= n < t2) && P n -> x' <= n t': nat LT: t1 <= t' Pt': P t'
x' <= t'
P: pred nat t1, t2: nat x: Datatypes_nat__canonical__eqtype_Equality IN: t1 <= x < t2 Px: P x EX: existsn : nat, (t1 <= n < t2) && P n x': nat IN': t1 <= x' < t2 Px': P x' MIN: foralln : nat, (t1 <= n < t2) && P n -> x' <= n t': nat LT: t1 <= t' Pt': P t' NEQ2: t' < t2
x' <= t'
byapply: MIN; repeat(apply/andP; split => //).}Qed.(** Next, we proceed to the function [search_arg]. *)SectionArgSearch.(* Given a function [f] that maps the naturals to elements of type [T]... *)Context {T : Type}.Variablef: nat -> T.(* ... a predicate [P] on [T] ... *)VariableP: pred T.(* ... and an order [R] on [T] ... *)VariableR: rel T.(* ... we define the procedure [search_arg] to iterate a given search space [a, b), while checking each element whether [f] satisfies [P] at that point and returning the extremum as defined by [R]. *)Fixpointsearch_arg (ab : nat) : option nat :=
if a < b thenmatch b with
| 0 => None
| S b' => match search_arg a b' with
| None => if P (f b') then Some b' else None
| Some x => if P (f b') && R (f b') (f x) then Some b' else Some x
endendelse None.(** In the following, we establish basic properties of [search_arg]. *)(* To begin, we observe that the search yields [None] iff predicate [P] does not hold for any of the points in the search interval. *)
T: Type f: nat -> T P: pred T R: rel T
forallab : nat,
search_arg a b = None <->
(forallx : nat, a <= x < b -> ~~ P (f x))
T: Type f: nat -> T P: pred T R: rel T
forallab : nat,
search_arg a b = None <->
(forallx : nat, a <= x < b -> ~~ P (f x))
T: Type f: nat -> T P: pred T R: rel T a, b: nat
search_arg a b = None ->
forallx : nat, a <= x < b -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b: nat
(forallx : nat, a <= x < b -> ~~ P (f x)) ->
search_arg a b = None
T: Type f: nat -> T P: pred T R: rel T a, b: nat
search_arg a b = None ->
forallx : nat, a <= x < b -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x)
search_arg a b'.+1 = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x)
(if a < b'.+1thenmatch search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
endelse None) = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) a_lt_b: a < b'.+1
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
end = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) not_a_lt_b': ~~ (a < b'.+1) TRIV: None = None
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) a_lt_b: a < b'.+1
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
end = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1
(search_arg a b' = None ->
forallx : nat, a <= x < b' -> ~~ P (f x)) ->
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
end = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 y: nat
(Some y = None ->
forallx : nat, a <= x < b' -> ~~ P (f x)) ->
(if P (f b') && R (f b') (f y)
then Some b'
else Some y) = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat
a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 y: nat
(Some y = None ->
forallx : nat, a <= x < b' -> ~~ P (f x)) ->
(if P (f b') && R (f b') (f y)
then Some b'
else Some y) = None ->
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
case: (P (f b') && R (f b') (f y)) => //.
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat
a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x x_lt_b': x < b'.+1
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x
x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x EQ: x = b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x LT: x < b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x EQ: x = b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x EQ: x = b'
~~ P (f b')
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) x: nat a_le_x: a <= x EQ: x = b'
(if P (f b') then Some b' else None) = None ->
~~ P (f b')
case: (P (f b')) => //.
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: None = None ->
forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x LT: x < b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x LT: x < b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat a_lt_b: a < b'.+1 HYP: forallx : nat, a <= x < b' -> ~~ P (f x) NIL: (if P (f b') then Some b' else None) = None x: nat a_le_x: a <= x LT: x < b'
a <= x < b'
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) not_a_lt_b': ~~ (a < b'.+1) TRIV: None = None
forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) not_a_lt_b': ~~ (a < b'.+1) TRIV: None = None x: nat a_le_x: a <= x b_lt_b': x < b'.+1
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) not_a_lt_b': ~~ (a < b'.+1) TRIV: None = None x: nat a_le_x: a <= x b_lt_b': x < b'.+1
False
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) TRIV: None = None x: nat a_le_x: a <= x b_lt_b': x < b'.+1
~~ (a < b'.+1) -> False
T: Type f: nat -> T P: pred T R: rel T a, b': nat HYP: search_arg a b' = None -> forallx : nat, a <= x < b' -> ~~ P (f x) TRIV: None = None x: nat a_le_x: a <= x b_lt_b': x < b'.+1 b'_lt_a: ~ a <= b'
False
bymove: (leq_ltn_trans a_le_x b_lt_b').
T: Type f: nat -> T P: pred T R: rel T a, b: nat
(forallx : nat, a <= x < b -> ~~ P (f x)) ->
search_arg a b = None
T: Type f: nat -> T P: pred T R: rel T a, b: nat
(forallx : nat, a <= x < b -> ~~ P (f x)) ->
search_arg a b = None
T: Type f: nat -> T P: pred T R: rel T a, b: nat
(forallx : nat, a <= x < b -> ~~ P (f x)) ->
(fix search_arg (a b : nat) {struct b} : option nat :=
if a < b
thenmatch b with
| 0 => None
| b'.+1 =>
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
endendelse None) a b = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat
((forallx : nat, a <= x < b' -> ~~ P (f x)) ->
(fix search_arg (a b : nat) {struct b} :
option nat :=
if a < b
thenmatch b with
| 0 => None
| b'.+1 =>
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
endendelse None) a b' = None) ->
(forallx : nat, a <= x < b'.+1 -> ~~ P (f x)) ->
(if a < b'.+1thenmatch
(fix search_arg (a b : nat) {struct b} :
option nat :=
if a < b
thenmatch b with
| 0 => None
| b'.+1 =>
match search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None =>
if P (f b') then Some b' else None
endendelse None) a b'
with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
endelse None) = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
(if a < b'.+1thenmatch search_arg a b' with
| Some x =>
if P (f b') && R (f b') (f x)
then Some b'
else Some x
| None => if P (f b') then Some b' else None
endelse None) = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
search_arg a b' = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) ->
search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
(if a < b'.+1thenif P (f b') then Some b' else None
else None) = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
search_arg a b' = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) x: nat a_le_x: a <= x x_lt_n: x < b'
~~ P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) x: nat a_le_x: a <= x x_lt_n: x < b'
a <= x < b'.+1
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x)
(if a < b'.+1thenif P (f b') then Some b' else None
else None) = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) a_lt_b: a < b'.+1
(if P (f b') then Some b' else None) = None
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) a_lt_b: a < b'.+1
P (f b') = false
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) a_lt_b: a < b'.+1
~~ P (f b')
T: Type f: nat -> T P: pred T R: rel T a, b': nat IND: (forallx : nat, a <= x < b' -> ~~ P (f x)) -> search_arg a b' = None NOT_SAT: forallx : nat, a <= x < b'.+1 -> ~~ P (f x) a_lt_b: a < b'.+1
a <= b' < b'.+1
byapply /andP; split.}Qed.(* Conversely, if we know that [f] satisfies [P] for at least one point in the search space, then [search_arg] yields some point. *)
T: Type f: nat -> T P: pred T R: rel T
forallab : nat,
(existsx : nat, a <= x < b /\ P (f x)) ->
existsy : nat, search_arg a b = Some y
T: Type f: nat -> T P: pred T R: rel T
forallab : nat,
(existsx : nat, a <= x < b /\ P (f x)) ->
existsy : nat, search_arg a b = Some y
T: Type f: nat -> T P: pred T R: rel T a, b: nat H_exists: existsx : nat, a <= x < b /\ P (f x)
existsy : nat, search_arg a b = Some y
T: Type f: nat -> T P: pred T R: rel T a, b: nat H_exists: existsx : nat, a <= x < b /\ P (f x) SEARCH: search_arg a b = None
existsy : nat, None = Some y
T: Type f: nat -> T P: pred T R: rel T a, b: nat H_exists: existsx : nat, a <= x < b /\ P (f x)
search_arg a b = None -> existsy : nat, None = Some y
T: Type f: nat -> T P: pred T R: rel T a, b: nat H_exists: existsx : nat, a <= x < b /\ P (f x) NOT_exists: forallx : nat, a <= x < b -> ~~ P (f x)
existsy : nat, None = Some y
T: Type f: nat -> T P: pred T R: rel T a, b: nat H_exists: existsx : nat, a <= x < b /\ P (f x) NOT_exists: forallx : nat, a <= x < b -> ~~ P (f x)
False
T: Type f: nat -> T P: pred T R: rel T a, b: nat NOT_exists: forallx : nat, a <= x < b -> ~~ P (f x) x: nat RANGE: a <= x < b Pfx: P (f x)
False
bymove: (NOT_exists x RANGE) => /negP not_Pfx.Qed.(* Since [search_arg] considers only points at which [f] satisfies [P], if it returns a point, then that point satisfies [P]. *)
T: Type f: nat -> T P: pred T R: rel T
forallabx : nat, search_arg a b = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T
forallabx : nat, search_arg a b = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, b, x: nat
search_arg a b = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> P (f x)
search_arg a n.+1 = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> P (f x)
(if a < n.+1thenmatch search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
endelse None) = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> P (f x) a_lt_Sn: (a < n.+1) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> P (f x)
(a < n.+1) = true ->
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> P (f x)
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> P (f x) a_lt_Sn: (a <= n) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> P (f x)
destruct (search_arg a n) as [q|] eqn:REC;
destruct (P (f n)) eqn:Pfn => //=;
[elim: (R (f n) (f q)) => // |];
bymove=> x_is; injection x_is => <-.Qed.(* Since [search_arg] considers only points within a given range, if it returns a point, then that point lies within the given range. *)
T: Type f: nat -> T P: pred T R: rel T
forallabx : nat,
search_arg a b = Some x -> a <= x < b
T: Type f: nat -> T P: pred T R: rel T
forallabx : nat,
search_arg a b = Some x -> a <= x < b
T: Type f: nat -> T P: pred T R: rel T a, b, x: nat
search_arg a b = Some x -> a <= x < b
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> a <= x < n
search_arg a n.+1 = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> a <= x < n
(if a < n.+1thenmatch search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
endelse None) = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> a <= x < n a_lt_Sn: (a < n.+1) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> a <= x < n
(a < n.+1) = true ->
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat IND: search_arg a n = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
(if R (f n) (f q) then Some n else Some q) = Some x ->
a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
Some q = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat REC: search_arg a n = None IND: None = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
Some n = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
(if R (f n) (f q) then Some n else Some q) = Some x ->
a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true x_is: Some q = Some x
a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true x_is: Some q = Some x a_le_x: a <= x x_lt_n: x < n
a <= x < n.+1
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
Some q = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true x_is: Some q = Some x
a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n, q: nat REC: search_arg a n = Some q IND: Some q = Some x -> a <= x < n a_lt_Sn: (a <= n) = true x_is: Some q = Some x a_le_x: a <= x x_lt_n: x < n
a <= x < n.+1
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat REC: search_arg a n = None IND: None = Some x -> a <= x < n a_lt_Sn: (a <= n) = true
Some n = Some x -> a <= x < n.+1
T: Type f: nat -> T P: pred T R: rel T a, x, n: nat REC: search_arg a n = None IND: None = Some x -> a <= x < n a_lt_Sn: (a <= n) = true x_is: Some n = Some x
a <= x < n.+1
byinjection x_is => <-; apply /andP; split.Qed.(* Let us assume that [R] is a reflexive and transitive total order... *)HypothesisR_reflexive: reflexive R.HypothesisR_transitive: transitive R.HypothesisR_total: total R.(* ...then [search_arg] yields an extremum w.r.t. to [a, b), that is, if [search_arg] yields a point x, then [R (f x) (f y)] holds for any [y] in the search range [a, b) that satisfies [P]. *)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R
forallabx : nat,
search_arg a b = Some x ->
forally : nat, a <= y < b -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R
forallabx : nat,
search_arg a b = Some x ->
forally : nat, a <= y < b -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, b, x: nat SEARCH: search_arg a b = Some x
forally : nat, a <= y < b -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat
search_arg a n.+1 = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat
(if a < n.+1thenmatch search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
endelse None) = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a < n.+1) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat
(a < n.+1) = true ->
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true
match search_arg a n with
| Some x =>
if P (f n) && R (f n) (f x)
then Some n
else Some x
| None => if P (f n) then Some n else None
end = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true
(if R (f n) (f q) then Some n else Some q) = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false
Some q = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true
Some n = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true
(if R (f n) (f q) then Some n else Some q) = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true
(if R (f n) (f q) then Some n else Some q) = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f n) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f n) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f n) (f y)
byrewrite EQ; apply (R_reflexive (f n)).
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f n) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n HOLDS: a <= y < n -> P (f y) -> R (f q) (f y)
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = true some_x_is: Some n = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n HOLDS: a <= y < n -> P (f y) -> R (f q) (f y)
a <= y < n
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f q) (f n)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n R_nq: R (f n) (f q)
R (f q) (f n)
bymove: REL => /negP.
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n HOLDS: a <= y < n -> P (f y) -> R (f q) (f y)
R (f q) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
search_arg a n = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true REL: R (f n) (f q) = false some_x_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n HOLDS: a <= y < n -> P (f y) -> R (f q) (f y)
a <= y < n
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false
Some q = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y y_lt_Sn: y < n.+1 Pfy: P (f y)
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y)
y < n.+1 -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y)
y <= n -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
False
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n Pfn: ~ P (f n)
False
bysubst.
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n, q: nat REC: search_arg a n = Some q IND: forallx : nat,
Some q = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = false some_q_is: Some q = Some x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
a <= y < n
byapply /andP; split.
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true
Some n = Some x ->
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x
forally : nat,
a <= y < n.+1 -> P (f y) -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y y_lt_Sn: y < n.+1 Pfy: P (f y)
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y)
y < n.+1 -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y)
y <= n -> R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) EQ: y = n
R (f x) (f y)
byrewrite -n_is EQ; apply (R_reflexive (f n)).
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
R (f x) (f y)
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat REC: search_arg a n = None IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
False
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n
search_arg a n = None -> False
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n NONE: forallx : nat, a <= x < n -> ~~ P (f x)
False
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n NONE: forallx : nat, a <= x < n -> ~~ P (f x) not_Pfy: a <= y < n -> ~~ P (f y)
False
T: Type f: nat -> T P: pred T R: rel T R_reflexive: reflexive (T:=T) R R_transitive: transitive (T:=T) R R_total: total (T:=T) R a, n: nat IND: forallx : nat,
None = Some x ->
forally : nat,
a <= y < n -> P (f y) -> R (f x) (f y) x: nat a_lt_Sn: (a <= n) = true Pfn: P (f n) = true some_n_is: Some n = Some x n_is: n = x y: nat a_le_y: a <= y Pfy: P (f y) y_lt_n: y < n NONE: forallx : nat, a <= x < n -> ~~ P (f x) not_Pfy: ~~ P (f y)
False
bymove: not_Pfy => /negP.Qed.EndArgSearch.SectionExMinn.(* We show that the fact that the minimal satisfying argument [ex_minn ex] of a predicate [pred] satisfies another predicate [P] implies the existence of a minimal element that satisfies both [pred] and [P]. *)
forall (P : nat -> Prop) (pred : nat -> bool)
(ex0 : existsn : nat, pred n),
P (ex_minn (P:=pred) ex0) ->
existsn : nat,
P n /\
pred n /\ (foralln' : nat, pred n' -> n <= n')
forall (P : nat -> Prop) (pred : nat -> bool)
(ex0 : existsn : nat, pred n),
P (ex_minn (P:=pred) ex0) ->
existsn : nat,
P n /\
pred n /\ (foralln' : nat, pred n' -> n <= n')
P: nat -> Prop pred: nat -> bool ex: existsn : nat, pred n
P (ex_minn (P:=pred) ex) ->
existsn : nat,
P n /\
pred n /\ (foralln' : nat, pred n' -> n <= n')
P: nat -> Prop pred: nat -> bool ex: existsn : nat, pred n H: P (ex_minn (P:=pred) ex)
pred (ex_minn (P:=pred) ex)
P: nat -> Prop pred: nat -> bool ex: existsn : nat, pred n H: P (ex_minn (P:=pred) ex)
foralln' : nat, pred n' -> ex_minn (P:=pred) ex <= n'
all: have MIN := ex_minnP ex; move: MIN => [n Pn MIN]; auto.Qed.(* As a corollary, we show that if there is a constant [c] such that [P c], then the minimal satisfying argument [ex_minn ex] of a predicate [P] is less than or equal to [c]. *)
forall (P : nat -> bool) (exP : existsn : nat, P n)
(c : nat), P c -> ex_minn (P:=P) exP <= c
forall (P : nat -> bool) (exP : existsn : nat, P n)
(c : nat), P c -> ex_minn (P:=P) exP <= c
P: nat -> bool exP: existsn : nat, P n c: nat EX: P c
ex_minn (P:=P) exP <= c
P: nat -> bool exP: existsn : nat, P n c: nat EX: P c GT: c < ex_minn (P:=P) exP
False
P: nat -> bool exP: existsn : nat, P n c: nat EX: P c n: nat LT: c < n Pn: P n MIN: foralln' : nat, P n' -> n <= n'
False
P: nat -> bool exP: existsn : nat, P n c: nat EX: P c n: nat LT: c < n Pn: P n MIN: n <= c