Built with Alectryon, running Coq+SerAPI v8.16.0+0.16.3. 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.
From Tealeaves Require Export
Classes.EqDec_eq
Misc.NaturalNumbers.From Tealeaves Require Import
Theory.TraversableFunctor.Import List.ListNotations.Import ContainerFunctor.Notations.Import Monoid.Notations.(** * Transparent Atoms *)(**********************************************************************)Module TypeAtomModule <: UsualDecidableType.Parametername: Type.Definitiont := name.Parametereq_dec: forallxy: name, {x = y} + {x <> y}.Parameterfresh: list name -> name.Parameterfresh_not_in: foralll, ~ fresh l ∈ l.Parameterfreshen: list name -> name -> name.Parameterfreshen_spec1: forall (l: list name) (n: name),
~ (n ∈ l) -> freshen l n = n.Parameterfreshen_spec2: forall (l: list name) (n: name),
~ freshen l n ∈ l.Parameternat_of: name -> nat.#[export] Hint Resolve eq_dec: core.Include HasUsualEq <+ UsualIsEq <+ UsualIsEqOrig.EndAtomModule.(** * Transparent Atoms Implementation Support *)(**********************************************************************)(*(* Test if x is an element of l, returning a boolean *)Fixpoint list_in (x: nat) (l: list nat): bool := match l with | nil => false | y :: rest => (x ==b y) || list_in x rest end. *)(** ** Least Strict Upper Bound of a [list] *)(**********************************************************************)(** Return one greater than the greatest element in a list *)DefinitionSmax (l: list nat): nat :=
S (mapReduce (op := Monoid_op_max) (unit := Monoid_unit_max) id l).(** <<Smax l>> is greater than every element *)
forall (l : list nat) (a : nat), a ∈ l -> a < Smax l
forall (l : list nat) (a : nat), a ∈ l -> a < Smax l
l: list nat a: nat H: a ∈ l
a < Smax l
a: nat H: a ∈ []
a < Smax []
a0: nat l: list nat a: nat H: a ∈ (a0 :: l) IHl: a ∈ l -> a < Smax l
a < Smax (a0 :: l)
a: nat H: a ∈ []
a < Smax []
inversion H.
a0: nat l: list nat a: nat H: a ∈ (a0 :: l) IHl: a ∈ l -> a < Smax l
a < Smax (a0 :: l)
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < Smax (a0 :: l)
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (mapReduce id (a0 :: l))
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (mapReduce_list id (a0 :: l))
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (id a0 ● mapReduce_list id l)
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (Nat.max (id a0) (mapReduce_list id l))
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (Nat.max (id a0) (mapReduce id l))
a0: nat l: list nat a: nat H: a = a0 \/ a ∈ l IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case1: a = a0 IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case2: a ∈ l IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case1: a = a0 IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case2: a ∈ l IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case2: a < Smax l IHl: a ∈ l -> a < Smax l
a < S (Nat.max a0 (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case2: a < Smax l IHl: a ∈ l -> a < Smax l
a <
PeanoNat.Nat.max (S a0)
(S (mapReduce (funx : nat => x) l))
a0: nat l: list nat a: nat Case2: a < Smax l IHl: a ∈ l -> a < Smax l
a < PeanoNat.Nat.max (S a0) (Smax l)
lia.Qed.(** <<Smax l>> is not the list *)
foralll : list nat, ~ Smax l ∈ l
foralll : list nat, ~ Smax l ∈ l
l: list nat
~ Smax l ∈ l
l: list nat contra: Smax l ∈ l
False
l: list nat contra: Smax l < Smax l
False
lia.Qed.(** ** Testing Membership in a [list] *)(**********************************************************************)Fixpointnat_inb (x: nat) (l: list nat): bool :=
match l with
| nil => false
| y :: rest => (if x == y then true else false) || nat_inb x rest
end.Definitionnat_freshb (x: nat) (l: list nat): bool :=
negb (nat_inb x l).
forall (x : nat) (l : list nat),
nat_inb x l = true <-> x ∈ l
forall (x : nat) (l : list nat),
nat_inb x l = true <-> x ∈ l
x: nat l: list nat
nat_inb x l = true <-> x ∈ l
x: nat
nat_inb x [] = true <-> x ∈ []
x, a: nat l: list nat IHl: nat_inb x l = true <-> x ∈ l
nat_inb x (a :: l) = true <-> x ∈ (a :: l)
x: nat
nat_inb x [] = true <-> x ∈ []
x: nat
false = true <-> False
intuition.
x, a: nat l: list nat IHl: nat_inb x l = true <-> x ∈ l
nat_inb x (a :: l) = true <-> x ∈ (a :: l)
x, a: nat l: list nat IHl: nat_inb x l = true <-> x ∈ l
((if x == a then true else false) || nat_inb x l)%bool =
true <-> a = x \/ List.In x l
x, a: nat l: list nat IHl: nat_inb x l = true <-> x ∈ l
((if x == a then true else false) || nat_inb x l)%bool =
true <-> a = x \/ nat_inb x l = true
x, a: nat l: list nat
((if x == a then true else false) || nat_inb x l)%bool =
true <-> a = x \/ nat_inb x l = true
x, a: nat l: list nat
((if x == a then true else false) || true)%bool = true <->
a = x \/ true = true
x, a: nat l: list nat
((if x == a then true else false) || false)%bool =
true <-> a = x \/ false = true
x, a: nat l: list nat
((if x == a then true else false) || true)%bool = true <->
a = x \/ true = true
x, a: nat l: list nat
true = true <-> a = x \/ true = true
intuition.
x, a: nat l: list nat
((if x == a then true else false) || false)%bool =
true <-> a = x \/ false = true
x, a: nat l: list nat
(if x == a then true else false) = true <->
a = x \/ false = true
destruct_eq_args x a; intuition.Qed.
forall (x : nat) (l : list nat),
nat_inb x l = false <-> ~ x ∈ l
forall (x : nat) (l : list nat),
nat_inb x l = false <-> ~ x ∈ l
x: nat l: list nat
nat_inb x l = false <-> ~ x ∈ l
x: nat l: list nat
nat_inb x l = false <-> nat_inb x l <> true
destruct (nat_inb x l);
intuition.Qed.
forall (x : nat) (l : list nat),
nat_freshb x l = true <-> ~ x ∈ l
forall (x : nat) (l : list nat),
nat_freshb x l = true <-> ~ x ∈ l
x: nat l: list nat
nat_freshb x l = true <-> ~ x ∈ l
x: nat l: list nat
negb (nat_inb x l) = true <-> ~ x ∈ l
x: nat l: list nat b: bool Heqb: b = nat_inb x l
negb b = true <-> ~ x ∈ l
x: nat l: list nat b: bool Heqb: nat_inb x l = b
negb b = true <-> ~ x ∈ l
x: nat l: list nat Heqb: nat_inb x l = true
negb true = true <-> ~ x ∈ l
x: nat l: list nat Heqb: nat_inb x l = false
negb false = true <-> ~ x ∈ l
x: nat l: list nat Heqb: nat_inb x l = true
negb true = true <-> ~ x ∈ l
x: nat l: list nat Heqb: x ∈ l
negb true = true <-> ~ x ∈ l
intuition.
x: nat l: list nat Heqb: nat_inb x l = false
negb false = true <-> ~ x ∈ l
x: nat l: list nat Heqb: ~ x ∈ l
negb false = true <-> ~ x ∈ l
intuition.Qed.
forall (x : nat) (l : list nat),
nat_freshb x l = false <-> x ∈ l
forall (x : nat) (l : list nat),
nat_freshb x l = false <-> x ∈ l
x: nat l: list nat
nat_freshb x l = false <-> x ∈ l
x: nat l: list nat
negb (nat_inb x l) = false <-> x ∈ l
x: nat l: list nat b: bool Heqb: b = nat_inb x l
negb b = false <-> x ∈ l
x: nat l: list nat b: bool Heqb: nat_inb x l = b
negb b = false <-> x ∈ l
x: nat l: list nat Heqb: nat_inb x l = true
negb true = false <-> x ∈ l
x: nat l: list nat Heqb: nat_inb x l = false
negb false = false <-> x ∈ l
x: nat l: list nat Heqb: nat_inb x l = true
negb true = false <-> x ∈ l
x: nat l: list nat Heqb: x ∈ l
negb true = false <-> x ∈ l
intuition.
x: nat l: list nat Heqb: nat_inb x l = false
negb false = false <-> x ∈ l
x: nat l: list nat Heqb: ~ x ∈ l
negb false = false <-> x ∈ l
intuition.Qed.(** ** Computing Maximum Element Not in [list] *)(**********************************************************************)(* Compute the maximum element not in a list. Computed slightly funny to be structurally recursive. We start with an element known not to be in the list. Then we test all smaller numbers to see if they are elements, and track the smallest value known not to form an element as <<candidate>> <<current min>> is the smallest value *)Fixpointmin_fresh_rec
(gas: nat) (candidate: nat)
(l: list nat): nat :=
match gas with
| 0 => if nat_freshb 0 l
then0else candidate
| S g =>
if nat_freshb g l
then min_fresh_rec g g l
else min_fresh_rec g candidate l
end.
forall (gascandidate : nat) (l : list nat),
~ candidate ∈ l -> ~ min_fresh_rec gas candidate l ∈ l
forall (gascandidate : nat) (l : list nat),
~ candidate ∈ l -> ~ min_fresh_rec gas candidate l ∈ l
gas, candidate: nat l: list nat H: ~ candidate ∈ l
~ min_fresh_rec gas candidate l ∈ l
gas: nat l: list nat
forallcandidate : nat,
~ candidate ∈ l -> ~ min_fresh_rec gas candidate l ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l
~ min_fresh_rec 0 candidate l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l
~ min_fresh_rec (S gas) candidate l ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l
~ min_fresh_rec 0 candidate l ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l
~ (if nat_freshb 0 l then0else candidate) ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l b: bool Heqb: b = nat_freshb 0 l
~ (if b then0else candidate) ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l b: bool Heqb: nat_freshb 0 l = b
~ (if b then0else candidate) ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb 0 l = true
~ 0 ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb 0 l = false
~ candidate ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb 0 l = true
~ 0 ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: ~ 0 ∈ l
~ 0 ∈ l
auto.
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb 0 l = false
~ candidate ∈ l
l: list nat candidate: nat H: ~ candidate ∈ l Heqb: 0 ∈ l
~ candidate ∈ l
assumption.
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l
~ min_fresh_rec (S gas) candidate l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l
~
(if nat_freshb gas l
then min_fresh_rec gas gas l
else min_fresh_rec gas candidate l) ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l b: bool Heqb: b = nat_freshb gas l
~
(if b
then min_fresh_rec gas gas l
else min_fresh_rec gas candidate l) ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l b: bool Heqb: nat_freshb gas l = b
~
(if b
then min_fresh_rec gas gas l
else min_fresh_rec gas candidate l) ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = true
~ min_fresh_rec gas gas l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = false
~ min_fresh_rec gas candidate l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = true
~ min_fresh_rec gas gas l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = true
~ gas ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: ~ gas ∈ l
~ gas ∈ l
assumption.
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = false
~ min_fresh_rec gas candidate l ∈ l
gas: nat l: list nat IHgas: forallcandidate : nat,
~ candidate ∈ l ->
~ min_fresh_rec gas candidate l ∈ l candidate: nat H: ~ candidate ∈ l Heqb: nat_freshb gas l = false
~ candidate ∈ l
assumption.Qed.Definitionmin_fresh (l: list nat): nat :=
min_fresh_rec (Smax l) (Smax l) l.Definitionfreshen (l: list nat) (n: nat): nat :=
if nat_freshb n l then n
else min_fresh l.
forall (l : list nat) (n : nat),
{~ n ∈ l /\ freshen l n = n} +
{n ∈ l /\ freshen l n = min_fresh l}
forall (l : list nat) (n : nat),
{~ n ∈ l /\ freshen l n = n} +
{n ∈ l /\ freshen l n = min_fresh l}
l: list nat n: nat
{~ n ∈ l /\ freshen l n = n} +
{n ∈ l /\ freshen l n = min_fresh l}
l: list nat n: nat b: bool Heqb: b = nat_freshb n l
{~ n ∈ l /\ freshen l n = n} +
{n ∈ l /\ freshen l n = min_fresh l}
l: list nat n: nat b: bool Heqb: nat_freshb n l = b
{~ n ∈ l /\ freshen l n = n} +
{n ∈ l /\ freshen l n = min_fresh l}
l: list nat n: nat b: bool Heqb: nat_freshb n l = b
{~ n ∈ l /\
(if nat_freshb n l then n else min_fresh l) = n} +
{n ∈ l /\
(if nat_freshb n l then n else min_fresh l) =
min_fresh l}
l: list nat n: nat b: bool Heqb: nat_freshb n l = b
{~ n ∈ l /\ (if b then n else min_fresh l) = n} +
{n ∈ l /\ (if b then n else min_fresh l) = min_fresh l}
l: list nat n: nat Heqb: nat_freshb n l = true
{~ n ∈ l /\ n = n} + {n ∈ l /\ n = min_fresh l}
l: list nat n: nat Heqb: nat_freshb n l = false
{~ n ∈ l /\ min_fresh l = n} +
{n ∈ l /\ min_fresh l = min_fresh l}
l: list nat n: nat Heqb: nat_freshb n l = true
{~ n ∈ l /\ n = n} + {n ∈ l /\ n = min_fresh l}
l: list nat n: nat Heqb: nat_freshb n l = true
~ n ∈ l /\ n = n
apply nat_freshb_iff in Heqb; auto.
l: list nat n: nat Heqb: nat_freshb n l = false
{~ n ∈ l /\ min_fresh l = n} +
{n ∈ l /\ min_fresh l = min_fresh l}