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.
forall (A : Type) (a1a2 : A) (xs : list A),
~ a1 ∈ (a2 :: xs) <-> a1 <> a2 /\ ~ a1 ∈ xs
forall (A : Type) (a1a2 : A) (xs : list A),
~ a1 ∈ (a2 :: xs) <-> a1 <> a2 /\ ~ a1 ∈ xs
A: Type a1, a2: A xs: list A
~ a1 ∈ (a2 :: xs) <-> a1 <> a2 /\ ~ a1 ∈ xs
A: Type a1, a2: A xs: list A
~ (a1 = a2 \/ a1 ∈ xs) <-> a1 <> a2 /\ ~ a1 ∈ xs
intuition.Qed.
forall (AB : Type) (f : A -> B) (x : option A)
(y : A),
(forallaa' : A, f a = f a' -> a = a') ->
map f x = Some (f y) -> x = Some y
forall (AB : Type) (f : A -> B) (x : option A)
(y : A),
(forallaa' : A, f a = f a' -> a = a') ->
map f x = Some (f y) -> x = Some y
A, B: Type f: A -> B x: option A y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f x = Some (f y)
x = Some y
A, B: Type f: A -> B a, y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f (Some a) = Some (f y)
Some a = Some y
A, B: Type f: A -> B y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f None = Some (f y)
None = Some y
A, B: Type f: A -> B a, y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f (Some a) = Some (f y)
Some a = Some y
A, B: Type f: A -> B a, y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f (Some a) = Some (f y) H0: f a = f y
Some a = Some y
A, B: Type f: A -> B a, y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f (Some a) = Some (f y) H0: f a = f y
a = y
A, B: Type f: A -> B a, y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f (Some a) = Some (f y) H0: f a = f y
f a = f y
assumption.
A, B: Type f: A -> B y: A Hinj: forallaa' : A, f a = f a' -> a = a' Heq: map f None = Some (f y)
None = Some y
inversion Heq.Qed.Ltaccompare_atoms :=
match goal with
| H: context[?a == ?a'] |- _ =>
destruct_eq_args a a'
| |- context[?a == ?a'] =>
destruct_eq_args a a'
end.#[global] Tactic Notation"compare""atoms" := compare_atoms.(** * Definition of <<key>> and main operations *)(******************************************************************************)Definitionkey :=
list atom.(** ** Insertion and lookup *)(******************************************************************************)Fixpointkey_insert_atom (k: key) (a: atom): key :=
match k with
| nil => [a]
| cons x rest =>
if a == x then k else
x :: key_insert_atom rest a
end.FixpointgetIndex (k: key) (a: atom): option nat :=
match k with
| [] => None
| x :: rest =>
if a == x
then Some 0else map S (getIndex rest a)
end.FixpointgetName (k: key) (ix: nat): option atom :=
match k, ix with
| nil, _ => None
| cons a rest, 0 => Some a
| cons a rest, S ix => getName rest ix
end.FixpointgetIndex_rec (k: key) (acc: nat) (a: atom): option nat :=
match k with
| nil => None
| cons x rest =>
if a == x then Some acc else getIndex_rec rest (S acc) a
end.DefinitiongetIndex_alt: key -> atom -> option nat :=
funk => getIndex_rec k 0.(** ** Well-formedness predicates *)(******************************************************************************)Fixpointunique (l: list atom): Prop :=
match l with
| nil => True
| cons a rest =>
~ (a ∈ rest) /\ unique rest
end.Definitionwf_LN
`{ToSubset T} (t: T LN) (k: key): Prop :=
unique k /\ forall (x: atom), Fr x ∈ t -> x ∈ k.Definitionresolves_gap (gap: nat) (k: key): Prop :=
gap <= length k.Definitioncontains_ix_upto (n: nat) (k: key): Prop :=
n < length k.
forall (gap : nat) (k : key),
resolves_gap gap k <->
contains_ix_upto (gap - 1) k \/ gap = 0
forall (gap : nat) (k : key),
resolves_gap gap k <->
contains_ix_upto (gap - 1) k \/ gap = 0
gap: nat k: key
resolves_gap gap k <->
contains_ix_upto (gap - 1) k \/ gap = 0
gap: nat k: key
gap <= length k <-> gap - 1 < length k \/ gap = 0
gap: nat k: key
gap <= length k -> gap - 1 < length k \/ gap = 0
gap: nat k: key
gap - 1 < length k \/ gap = 0 -> gap <= length k
gap: nat k: key
gap <= length k -> gap - 1 < length k \/ gap = 0
lia.
gap: nat k: key
gap - 1 < length k \/ gap = 0 -> gap <= length k
lia.Qed.
forall (a : atom) (l : list atom), decidable (a ∈ l)
forall (a : atom) (l : list atom), decidable (a ∈ l)
a: atom l: list atom
decidable (a ∈ l)
a: atom
decidable (a ∈ [])
a, a0: atom l: list atom IHl: decidable (a ∈ l)
decidable (a ∈ (a0 :: l))
a: atom
decidable (a ∈ [])
a: atom
~ a ∈ []
a: atom
~ False
easy.
a, a0: atom l: list atom IHl: decidable (a ∈ l)
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Huniq: a ∈ l
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Hnuniq: ~ a ∈ l
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Huniq: a ∈ l
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Huniq: a ∈ l
a ∈ (a0 :: l)
a, a0: atom l: list atom Huniq: a ∈ l
a = a0 \/ a ∈ l
tauto.
a, a0: atom l: list atom Hnuniq: ~ a ∈ l
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Hnuniq: ~ a ∈ l e: a = a0
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Hnuniq: ~ a ∈ l n: a <> a0
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Hnuniq: ~ a ∈ l e: a = a0
decidable (a ∈ (a0 :: l))
a0: atom l: list atom Hnuniq: ~ a0 ∈ l
decidable (a0 ∈ (a0 :: l))
a0: atom l: list atom Hnuniq: ~ a0 ∈ l
a0 ∈ (a0 :: l)
a0: atom l: list atom Hnuniq: ~ a0 ∈ l
a0 = a0 \/ a0 ∈ l
nowleft.
a, a0: atom l: list atom Hnuniq: ~ a ∈ l n: a <> a0
decidable (a ∈ (a0 :: l))
a, a0: atom l: list atom Hnuniq: ~ a ∈ l n: a <> a0
~ a ∈ (a0 :: l)
a, a0: atom l: list atom Hnuniq: ~ a ∈ l n: a <> a0
~ (a = a0 \/ a ∈ l)
tauto.Qed.
foralll : list atom, decidable (unique l)
foralll : list atom, decidable (unique l)
l: list atom
decidable (unique l)
decidable (unique [])
a: atom l: list atom IHl: decidable (unique l)
decidable (unique (a :: l))
decidable (unique [])
unique []
True
easy.
a: atom l: list atom IHl: decidable (unique l)
decidable (unique (a :: l))
a: atom l: list atom Huniq: unique l
decidable (unique (a :: l))
a: atom l: list atom Hnuniq: ~ unique l
decidable (unique (a :: l))
a: atom l: list atom Huniq: unique l
decidable (unique (a :: l))
a: atom l: list atom Huniq: unique l
decidable (~ a ∈ l /\ unique l)
a: atom l: list atom Huniq: unique l H: a ∈ l
decidable (~ a ∈ l /\ unique l)
a: atom l: list atom Huniq: unique l H: ~ a ∈ l
decidable (~ a ∈ l /\ unique l)
a: atom l: list atom Huniq: unique l H: a ∈ l
decidable (~ a ∈ l /\ unique l)
a: atom l: list atom Huniq: unique l H: a ∈ l
~ (~ a ∈ l /\ unique l)
tauto.
a: atom l: list atom Huniq: unique l H: ~ a ∈ l
decidable (~ a ∈ l /\ unique l)
a: atom l: list atom Huniq: unique l H: ~ a ∈ l
~ a ∈ l /\ unique l
tauto.
a: atom l: list atom Hnuniq: ~ unique l
decidable (unique (a :: l))
a: atom l: list atom Hnuniq: ~ unique l
~ unique (a :: l)
a: atom l: list atom Hnuniq: ~ unique l
~ (~ a ∈ l /\ unique l)
tauto.Qed.(*Definition wf_DB `{ToCtxset nat T} (t: T nat) (k: key): Prop := unique k /\ exists (gap: nat), cl_at gap t /\ resolves_gap gap k.*)(** * Misc *)(******************************************************************************)
k: key a: atom
{a ∈ k} + {~ a ∈ k}
k: key a: atom
{a ∈ k} + {~ a ∈ k}
a: atom
{a ∈ []} + {~ a ∈ []}
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k}
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a: atom
{a ∈ []} + {~ a ∈ []}
a: atom
~ a ∈ []
inversion1.
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k}
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k} i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k} i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k e: a = a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k} i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k} i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k e: a = a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
now (left; left).
a0: atom k: list atom a: atom IHk: {a ∈ k} + {~ a ∈ k} i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom e: a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom n0: ~ a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom e: a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
now (left; right).
a0: atom k: list atom a: atom n0: ~ a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
{a ∈ (a0 :: k)} + {~ a ∈ (a0 :: k)}
a0: atom k: list atom a: atom n0: ~ a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
~ a ∈ (a0 :: k)
a0: atom k: list atom a: atom n0: ~ a ∈ k i:= element_of_list_cons a a0 k: a ∈ (a0 :: k) <-> a = a0 \/ a ∈ k n: a <> a0
~ (a = a0 \/ a ∈ k)
intros [contra|contra];
contradiction.Defined.
k: key ix: nat
{contains_ix_upto ix k} + {~ contains_ix_upto ix k}
k: key ix: nat
{contains_ix_upto ix k} + {~ contains_ix_upto ix k}
apply Compare_dec.le_dec.Defined.(** * Lemmas about <<key_insert_atom>> *)(******************************************************************************)(** ** Rewriting *)(******************************************************************************)
forall (a : atom) (k : list atom) (x : atom),
a = x -> key_insert_atom (a :: k) x = a :: k
forall (a : atom) (k : list atom) (x : atom),
a = x -> key_insert_atom (a :: k) x = a :: k
a: atom k: list atom x: atom H: a = x
key_insert_atom (a :: k) x = a :: k
a: atom k: list atom x: atom H: a = x
(if x == a then a :: k else a :: key_insert_atom k x) =
a :: k
destruct_eq_args x a.Qed.
forall (a : atom) (k : list atom) (x : atom),
a <> x ->
key_insert_atom (a :: k) x = a :: key_insert_atom k x
forall (a : atom) (k : list atom) (x : atom),
a <> x ->
key_insert_atom (a :: k) x = a :: key_insert_atom k x
a: atom k: list atom x: atom H: a <> x
key_insert_atom (a :: k) x = a :: key_insert_atom k x
a: atom k: list atom x: atom H: a <> x
(if x == a then a :: k else a :: key_insert_atom k x) =
a :: key_insert_atom k x
destruct_eq_args x a.Qed.(** ** Alternative spec *)(******************************************************************************)
k: key a: atom n: nat
getIndex_rec k n a =
map (funm : nat => m + n) (getIndex k a)
k: key a: atom n: nat
getIndex_rec k n a =
map (funm : nat => m + n) (getIndex k a)
k: key a: atom
foralln : nat,
getIndex_rec k n a =
map (funm : nat => m + n) (getIndex k a)
a: atom n: nat
getIndex_rec [] n a =
map (funm : nat => m + n) (getIndex [] a)
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat
getIndex_rec (a0 :: k) n a =
map (funm : nat => m + n) (getIndex (a0 :: k) a)
a: atom n: nat
getIndex_rec [] n a =
map (funm : nat => m + n) (getIndex [] a)
reflexivity.
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat
getIndex_rec (a0 :: k) n a =
map (funm : nat => m + n) (getIndex (a0 :: k) a)
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat
(if a == a0 then Some n else getIndex_rec k (S n) a) =
map (funm : nat => m + n)
(if a == a0 then Some 0else map S (getIndex k a))
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat e: a = a0
Some n = map (funm : nat => m + n) (Some 0)
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
getIndex_rec k (S n) a =
map (funm : nat => m + n) (map S (getIndex k a))
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat e: a = a0
Some n = map (funm : nat => m + n) (Some 0)
reflexivity.
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
getIndex_rec k (S n) a =
map (funm : nat => m + n) (map S (getIndex k a))
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
map (funm : nat => m + S n) (getIndex k a) =
map (funm : nat => m + n) (map S (getIndex k a))
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
map (funm : nat => m + S n) (getIndex k a) =
(map (funm : nat => m + n) ∘ map S) (getIndex k a)
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
map (funm : nat => m + S n) (getIndex k a) =
map ((funm : nat => m + n) ∘ S) (getIndex k a)
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0
(funm : nat => m + S n) = (funm : nat => m + n) ∘ S
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0 m: nat
m + S n = ((funm : nat => m + n) ∘ S) m
a0: atom k: list atom a: atom IHk: foralln : nat,
getIndex_rec k n a = map (funm : nat => m + n) (getIndex k a) n: nat n0: a <> a0 m: nat
m + S n = S (m + n)
lia.Qed.
k: key a: atom
getIndex_alt k a = getIndex k a
k: key a: atom
getIndex_alt k a = getIndex k a
k: key a: atom
getIndex_rec k 0 a = getIndex k a
k: key a: atom
map (funm : nat => m + 0) (getIndex k a) =
getIndex k a
k: key a: atom
map id (getIndex k a) = getIndex k a
k: key a: atom
id = (funm : nat => m + 0)
k: key a: atom
id = (funm : nat => m + 0)
k: key a: atom m: nat
id m = m + 0
k: key a: atom m: nat
m = m + 0
lia.Qed.(** ** Insertion and <<unique>> *)(******************************************************************************)
forall (k : list atom) (aa' : atom),
a <> a' -> ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
forall (k : list atom) (aa' : atom),
a <> a' -> ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
k: list atom a, a': atom Hneq: a <> a' Hnin: ~ a ∈ k
~ a ∈ key_insert_atom k a'
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ []
~ a ∈ key_insert_atom [] a'
a0: atom k: list atom a, a': atom Hneq: a <> a' Hnin: ~ a ∈ (a0 :: k) IHk: ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
~ a ∈ key_insert_atom (a0 :: k) a'
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ []
~ a ∈ key_insert_atom [] a'
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ []
~ (a' = a \/ False)
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ [] H1: a' = a
False
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ [] H2: False
False
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ [] H1: a' = a
False
nowsubst.
a, a': atom Hneq: a <> a' Hnin: ~ a ∈ [] H2: False
False
assumption.
a0: atom k: list atom a, a': atom Hneq: a <> a' Hnin: ~ a ∈ (a0 :: k) IHk: ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
~ a ∈ key_insert_atom (a0 :: k) a'
a0: atom k: list atom a, a': atom Hneq: a <> a' Hnin: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
~ a ∈ key_insert_atom (a0 :: k) a'
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ k -> ~ a ∈ key_insert_atom k a'
~ a ∈ key_insert_atom (a0 :: k) a'
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a'
~ a ∈ key_insert_atom (a0 :: k) a'
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a'
~
List.In a
(if a' == a0
then a0 :: k
else a0 :: key_insert_atom k a')
a0: atom k: list atom a: atom Hneq, H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a0 DESTR_EQs: a0 = a0
~ List.In a (a0 :: k)
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a' DESTR_NEQ: a' <> a0 DESTR_NEQs: a0 <> a'
~ List.In a (a0 :: key_insert_atom k a')
a0: atom k: list atom a: atom Hneq, H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a0 DESTR_EQs: a0 = a0
~ List.In a (a0 :: k)
a0: atom k: list atom a: atom Hneq, H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a0 DESTR_EQs: a0 = a0 contra: a0 = a
False
a0: atom k: list atom a: atom Hneq, H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a0 DESTR_EQs: a0 = a0 contra: List.In a k
False
a0: atom k: list atom a: atom Hneq, H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a0 DESTR_EQs: a0 = a0 contra: List.In a k
False
contradiction.
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a' DESTR_NEQ: a' <> a0 DESTR_NEQs: a0 <> a'
~ List.In a (a0 :: key_insert_atom k a')
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a' DESTR_NEQ: a' <> a0 DESTR_NEQs: a0 <> a' contra: a0 = a
False
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a' DESTR_NEQ: a' <> a0 DESTR_NEQs: a0 <> a' contra: List.In a (key_insert_atom k a')
False
a0: atom k: list atom a, a': atom Hneq: a <> a' H: a <> a0 Hnin: ~ a ∈ k IHk: ~ a ∈ key_insert_atom k a' DESTR_NEQ: a' <> a0 DESTR_NEQs: a0 <> a' contra: List.In a (key_insert_atom k a')
False
contradiction.Qed.
k: key a: atom
unique k -> unique (key_insert_atom k a)
k: key a: atom
unique k -> unique (key_insert_atom k a)
k: key a: atom H: unique k
unique (key_insert_atom k a)
a: atom H: unique []
unique (key_insert_atom [] a)
a0: atom k: list atom a: atom H: unique (a0 :: k) IHk: unique k -> unique (key_insert_atom k a)
unique (key_insert_atom (a0 :: k) a)
a: atom H: unique []
unique (key_insert_atom [] a)
a: atom H: unique []
~ False /\ True
easy.
a0: atom k: list atom a: atom H: unique (a0 :: k) IHk: unique k -> unique (key_insert_atom k a)
unique (key_insert_atom (a0 :: k) a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique k -> unique (key_insert_atom k a)
unique (key_insert_atom (a0 :: k) a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique (key_insert_atom k a)
unique (key_insert_atom (a0 :: k) a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique (key_insert_atom k a)
unique
(if a == a0
then a0 :: k
else a0 :: key_insert_atom k a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique (key_insert_atom k a) DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
unique (a0 :: key_insert_atom k a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique (key_insert_atom k a) DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
~ a0 ∈ key_insert_atom k a /\
unique (key_insert_atom k a)
a0: atom k: list atom a: atom H1: ~ a0 ∈ k H2: unique k IHk: unique (key_insert_atom k a) DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
~ a0 ∈ key_insert_atom k a
apply key_nin_insert; auto.Qed.(** ** Insertion and <<getIndex>> *)(******************************************************************************)
forall (k : key) (a : atom),
~ a ∈ k -> getIndex k a = None
forall (k : key) (a : atom),
~ a ∈ k -> getIndex k a = None
k: key a: atom H: ~ a ∈ k
getIndex k a = None
a: atom H: ~ a ∈ []
getIndex [] a = None
a0: atom k: list atom a: atom H: ~ a ∈ (a0 :: k) IHk: ~ a ∈ k -> getIndex k a = None
getIndex (a0 :: k) a = None
a: atom H: ~ a ∈ []
getIndex [] a = None
reflexivity.
a0: atom k: list atom a: atom H: ~ a ∈ (a0 :: k) IHk: ~ a ∈ k -> getIndex k a = None
getIndex (a0 :: k) a = None
a0: atom k: list atom a: atom H: ~ a ∈ (a0 :: k) IHk: ~ a ∈ k -> getIndex k a = None
(if a == a0 then Some 0else map S (getIndex k a)) =
None
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None
(if a == a0 then Some 0else map S (getIndex k a)) =
None
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S (getIndex k a) = None
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S None = None
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
~ a ∈ k
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S None = None
reflexivity.
a0: atom k: list atom a: atom H: a <> a0 /\ ~ a ∈ k IHk: ~ a ∈ k -> getIndex k a = None DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
~ a ∈ k
intuition.Qed.
forall (k : key) (a : atom),
getIndex k a = None -> ~ a ∈ k
forall (k : key) (a : atom),
getIndex k a = None -> ~ a ∈ k
k: key a: atom hyp: getIndex k a = None
~ a ∈ k
a: atom hyp: getIndex [] a = None
~ a ∈ []
a0: atom k: list atom a: atom hyp: getIndex (a0 :: k) a = None IHk: getIndex k a = None -> ~ a ∈ k
~ a ∈ (a0 :: k)
a: atom hyp: getIndex [] a = None
~ a ∈ []
a: atom hyp: getIndex [] a = None
False -> False
easy.
a0: atom k: list atom a: atom hyp: getIndex (a0 :: k) a = None IHk: getIndex k a = None -> ~ a ∈ k
~ a ∈ (a0 :: k)
a0: atom k: list atom a: atom hyp: getIndex (a0 :: k) a = None IHk: getIndex k a = None -> ~ a ∈ k
a <> a0 /\ ~ a ∈ k
a0: atom k: list atom a: atom hyp: (if a == a0 then Some 0else map S (getIndex k a)) = None IHk: getIndex k a = None -> ~ a ∈ k
a <> a0 /\ ~ a ∈ k
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
a <> a0 /\ ~ a ∈ k
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
a <> a0
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
~ a ∈ k
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
a <> a0
assumption.
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
~ a ∈ k
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S (getIndex k a) = None IHk: getIndex k a = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
getIndex k a = None
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 n: nat hyp: map S (Some n) = None IHk: Some n = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
Some n = None
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S None = None IHk: None = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
None = None
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 n: nat hyp: map S (Some n) = None IHk: Some n = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
Some n = None
inversion hyp.
a0: atom k: list atom a: atom DESTR_NEQ: a <> a0 hyp: map S None = None IHk: None = None -> ~ a ∈ k DESTR_NEQs: a0 <> a
None = None
reflexivity.Qed.
forall (k : key) (a : atom),
~ a ∈ k <-> getIndex k a = None
forall (k : key) (a : atom),
~ a ∈ k <-> getIndex k a = None
k: key a: atom
~ a ∈ k <-> getIndex k a = None
k: key a: atom
~ a ∈ k -> getIndex k a = None
k: key a: atom
getIndex k a = None -> ~ a ∈ k
k: key a: atom
~ a ∈ k -> getIndex k a = None
apply getIndex_not_in1.
k: key a: atom
getIndex k a = None -> ~ a ∈ k
apply getIndex_not_in2.Qed.
forall (k : key) (a : atom),
a ∈ k -> {n : nat | getIndex k a = Some n}
forall (k : key) (a : atom),
a ∈ k -> {n : nat | getIndex k a = Some n}
k: key a: atom Hin: a ∈ k
{n : nat | getIndex k a = Some n}
a: atom Hin: a ∈ []
{n : nat | getIndex [] a = Some n}
a0: atom k: list atom a: atom Hin: a ∈ (a0 :: k) IHk: a ∈ k -> {n : nat | getIndex k a = Some n}
{n : nat | getIndex (a0 :: k) a = Some n}
a: atom Hin: a ∈ []
{n : nat | getIndex [] a = Some n}
inversion Hin.
a0: atom k: list atom a: atom Hin: a ∈ (a0 :: k) IHk: a ∈ k -> {n : nat | getIndex k a = Some n}
{n : nat | getIndex (a0 :: k) a = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n}
{n : nat | getIndex (a0 :: k) a = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n}
{n : nat
| (if a == a0 then Some 0else map S (getIndex k a)) =
Some n}
a0: atom k: list atom IHk: a0 ∈ k -> {n : nat | getIndex k a0 = Some n} Hin: a0 = a0 \/ a0 ∈ k DESTR_EQs: a0 = a0
{n : nat | Some 0 = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n} DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
{n : nat | map S (getIndex k a) = Some n}
a0: atom k: list atom IHk: a0 ∈ k -> {n : nat | getIndex k a0 = Some n} Hin: a0 = a0 \/ a0 ∈ k DESTR_EQs: a0 = a0
{n : nat | Some 0 = Some n}
now (exists0).
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n} DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
{n : nat | map S (getIndex k a) = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n} DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a Hink: a ∈ k
{n : nat | map S (getIndex k a) = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n} DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a Hink: a ∈ k m: nat Hm: getIndex k a = Some m
{n : nat | map S (getIndex k a) = Some n}
a0: atom k: list atom a: atom Hin: a = a0 \/ a ∈ k IHk: a ∈ k -> {n : nat | getIndex k a = Some n} DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a Hink: a ∈ k m: nat Hm: getIndex k a = Some m
{n : nat | map S (Some m) = Some n}
now (exists (Sm)).Qed.
forall (k : key) (a : atom) (n : nat),
getIndex k a = Some n -> a ∈ k
forall (k : key) (a : atom) (n : nat),
getIndex k a = Some n -> a ∈ k
k: key a: atom
foralln : nat, getIndex k a = Some n -> a ∈ k
a: atom n: nat Heq: getIndex [] a = Some n
a ∈ []
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat Heq: getIndex (a0 :: k) a = Some n
a ∈ (a0 :: k)
a: atom n: nat Heq: getIndex [] a = Some n
a ∈ []
inversion Heq.
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat Heq: getIndex (a0 :: k) a = Some n
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat Heq: getIndex (a0 :: k) a = Some n
a = a0 \/ a ∈ k
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat Heq: (if a == a0 then Some 0else map S (getIndex k a)) = Some n
a = a0 \/ a ∈ k
a0: atom k: list atom IHk: foralln : nat, getIndex k a0 = Some n -> a0 ∈ k n: nat Heq: Some 0 = Some n DESTR_EQs: a0 = a0
a0 = a0 \/ a0 ∈ k
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat DESTR_NEQ: a <> a0 Heq: map S (getIndex k a) = Some n DESTR_NEQs: a0 <> a
a = a0 \/ a ∈ k
a0: atom k: list atom IHk: foralln : nat, getIndex k a0 = Some n -> a0 ∈ k n: nat Heq: Some 0 = Some n DESTR_EQs: a0 = a0
a0 = a0 \/ a0 ∈ k
nowleft.
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat DESTR_NEQ: a <> a0 Heq: map S (getIndex k a) = Some n DESTR_NEQs: a0 <> a
a = a0 \/ a ∈ k
a0: atom k: list atom a: atom IHk: foralln : nat, getIndex k a = Some n -> a ∈ k n: nat DESTR_NEQ: a <> a0 Heq: map S (getIndex k a) = Some n DESTR_NEQs: a0 <> a
a ∈ k
a0: atom k: list atom a: atom n0: nat IHk: foralln : nat, Some n0 = Some n -> a ∈ k n: nat DESTR_NEQ: a <> a0 Heq: map S (Some n0) = Some n DESTR_NEQs: a0 <> a H0: S n0 = n
a ∈ k
noweapply IHk.Qed.
forall (k : key) (a : atom),
(existsn : nat, getIndex k a = Some n) <-> a ∈ k
forall (k : key) (a : atom),
(existsn : nat, getIndex k a = Some n) <-> a ∈ k
k: key a: atom
(existsn : nat, getIndex k a = Some n) <-> a ∈ k
k: key a: atom
(existsn : nat, getIndex k a = Some n) -> a ∈ k
k: key a: atom
a ∈ k -> existsn : nat, getIndex k a = Some n
k: key a: atom
(existsn : nat, getIndex k a = Some n) -> a ∈ k
k: key a: atom n: nat H: getIndex k a = Some n
a ∈ k
eauto using getIndex_in2.
k: key a: atom
a ∈ k -> existsn : nat, getIndex k a = Some n
k: key a: atom Hin: a ∈ k
existsn : nat, getIndex k a = Some n
k: key a: atom Hin: {n : nat | getIndex k a = Some n}
existsn : nat, getIndex k a = Some n
firstorder.Qed.
forall (k : key) (a : atom),
(a ∈ k) * {n : nat | getIndex k a = Some n} +
{~ a ∈ k /\ getIndex k a = None}
forall (k : key) (a : atom),
(a ∈ k) * {n : nat | getIndex k a = Some n} +
{~ a ∈ k /\ getIndex k a = None}
k: key a: atom
(a ∈ k) * {n : nat | getIndex k a = Some n} +
{~ a ∈ k /\ getIndex k a = None}
k: key a: atom e: a ∈ k
((a ∈ k) * {n : nat | getIndex k a = Some n})%type
k: key a: atom n: ~ a ∈ k
~ a ∈ k /\ getIndex k a = None
k: key a: atom e: a ∈ k
((a ∈ k) * {n : nat | getIndex k a = Some n})%type
k: key a: atom e: a ∈ k
a ∈ k
k: key a: atom e: a ∈ k
{n : nat | getIndex k a = Some n}
k: key a: atom e: a ∈ k
a ∈ k
assumption.
k: key a: atom e: a ∈ k
{n : nat | getIndex k a = Some n}
auto using getIndex_in1.
k: key a: atom n: ~ a ∈ k
~ a ∈ k /\ getIndex k a = None
k: key a: atom n: ~ a ∈ k
~ a ∈ k
k: key a: atom n: ~ a ∈ k
getIndex k a = None
k: key a: atom n: ~ a ∈ k
~ a ∈ k
assumption.
k: key a: atom n: ~ a ∈ k
getIndex k a = None
auto using getIndex_not_in1.Defined.Ltaclookup_atom_in_key k a :=
letn := fresh"n"inletHin := fresh"H_in"inletHnin := fresh"H_not_in"indestruct (getIndex_decide k a) as
[[Hin [n H_key_lookup]] | [Hnin H_key_lookup]];
trycontradiction.Tactic Notation"lookup""atom"constr(a) "in""key"constr(k) :=
lookup_atom_in_key k a.
forall (k : key) (a : atom), a ∈ k \/ ~ a ∈ k
forall (k : key) (a : atom), a ∈ k \/ ~ a ∈ k
k: key a: atom
a ∈ k \/ ~ a ∈ k
k: key a: atom H_in: a ∈ k n: nat H_key_lookup: getIndex k a = Some n
a ∈ k \/ ~ a ∈ k
k: key a: atom H_not_in: ~ a ∈ k H_key_lookup: getIndex k a = None
a ∈ k \/ ~ a ∈ k
k: key a: atom H_in: a ∈ k n: nat H_key_lookup: getIndex k a = Some n
a ∈ k \/ ~ a ∈ k
k: key a: atom H_in: a ∈ k n: nat H_key_lookup: getIndex k a = Some n
a ∈ k
intuition.
k: key a: atom H_not_in: ~ a ∈ k H_key_lookup: getIndex k a = None
a ∈ k \/ ~ a ∈ k
nowright.Qed.
forall (aa' : atom) (k : list atom),
getIndex (a :: k) a' = Some 0 -> a = a'
forall (aa' : atom) (k : list atom),
getIndex (a :: k) a' = Some 0 -> a = a'
a, a': atom k: list atom Hlookup: (if a' == a
then Some 0else map S (getIndex k a')) =
Some 0
a = a'
a, a': atom k: list atom DESTR_NEQ: a' <> a Hlookup: map S (getIndex k a') = Some 0 DESTR_NEQs: a <> a'
a = a'
lookup atom a' in key k;
rewrite H_key_lookup in Hlookup;
nowinversion Hlookup.Qed.
forall (ax : atom) (k : list atom) (ix : nat),
getIndex (x :: k) a = Some (S ix) ->
a <> x /\ getIndex k a = Some ix
forall (ax : atom) (k : list atom) (ix : nat),
getIndex (x :: k) a = Some (S ix) ->
a <> x /\ getIndex k a = Some ix
a, x: atom k: list atom ix: nat HH: getIndex (x :: k) a = Some (S ix)
a <> x /\ getIndex k a = Some ix
a, x: atom k: list atom ix: nat HH: (if a == x then Some 0else map S (getIndex k a)) =
Some (S ix)
a <> x /\ getIndex k a = Some ix
a, x: atom k: list atom ix: nat DESTR_NEQ: a <> x HH: map S (getIndex k a) = Some (S ix) DESTR_NEQs: x <> a
a <> x /\ getIndex k a = Some ix
a, x: atom k: list atom ix: nat DESTR_NEQ: a <> x HH: map S (getIndex k a) = Some (S ix) DESTR_NEQs: x <> a
a <> x
a, x: atom k: list atom ix: nat DESTR_NEQ: a <> x HH: map S (getIndex k a) = Some (S ix) DESTR_NEQs: x <> a
getIndex k a = Some ix
a, x: atom k: list atom ix: nat DESTR_NEQ: a <> x HH: map S (getIndex k a) = Some (S ix) DESTR_NEQs: x <> a
getIndex k a = Some ix
eauto using (map_Some_inv S).Qed.
forall (a : atom) (k : list atom) (a' : atom)
(ix : nat),
getIndex (a :: k) a' = Some ix ->
a' = a /\ ix = 0 \/
a' <> a /\
(existsix' : nat,
ix = S ix' /\ getIndex k a' = Some ix')
forall (a : atom) (k : list atom) (a' : atom)
(ix : nat),
getIndex (a :: k) a' = Some ix ->
a' = a /\ ix = 0 \/
a' <> a /\
(existsix' : nat,
ix = S ix' /\ getIndex k a' = Some ix')
a: atom k: list atom a': atom ix: nat Hyp: getIndex (a :: k) a' = Some ix
a' = a /\ ix = 0 \/
a' <> a /\
(existsix' : nat,
ix = S ix' /\ getIndex k a' = Some ix')
a: atom k: list atom a': atom Hyp: getIndex (a :: k) a' = Some 0
a' = a /\ 0 = 0
a: atom k: list atom a': atom ix: nat Hyp: getIndex (a :: k) a' = Some (S ix)
a' <> a /\
(existsix' : nat,
S ix = S ix' /\ getIndex k a' = Some ix')
a: atom k: list atom a': atom Hyp: getIndex (a :: k) a' = Some 0
a' = a /\ 0 = 0
a: atom k: list atom a': atom Hyp: a = a'
a' = a /\ 0 = 0
intuition.
a: atom k: list atom a': atom ix: nat Hyp: getIndex (a :: k) a' = Some (S ix)
a' <> a /\
(existsix' : nat,
S ix = S ix' /\ getIndex k a' = Some ix')
a: atom k: list atom a': atom ix: nat Hyp: a' <> a /\ getIndex k a' = Some ix
a' <> a /\
(existsix' : nat,
S ix = S ix' /\ getIndex k a' = Some ix')
intuitioneauto.Qed.(** ** Insertion and <<key_lookup_ix>> *)(******************************************************************************)
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a -> a ∈ k
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a -> a ∈ k
k: key ix: nat a: atom Hin: getName k ix = Some a
a ∈ k
k: key a: atom
forallix : nat, getName k ix = Some a -> a ∈ k
a: atom ix: nat Hin: getName [] ix = Some a
a ∈ []
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName (a0 :: k) ix = Some a
a ∈ (a0 :: k)
a: atom ix: nat Hin: getName [] ix = Some a
a ∈ []
inversion Hin.
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName (a0 :: k) ix = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k Hin: getName (a0 :: k) 0 = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName (a0 :: k) (S ix) = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k Hin: getName (a0 :: k) 0 = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k Hin: Some a0 = Some a
a0 = a \/ List.In a k
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k Hin: Some a0 = Some a H0: a0 = a
a = a \/ List.In a k
nowleft.
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName (a0 :: k) (S ix) = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName k ix = Some a
a ∈ (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName k ix = Some a
a = a0 \/ a ∈ k
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> a ∈ k ix: nat Hin: getName k ix = Some a
a ∈ k
eauto.Qed.
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a -> contains_ix_upto ix k
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a -> contains_ix_upto ix k
k: key ix: nat a: atom Hin: getName k ix = Some a
contains_ix_upto ix k
k: key ix: nat a: atom Hin: getName k ix = Some a
ix < length k
k: key a: atom
forallix : nat,
getName k ix = Some a -> ix < length k
a: atom ix: nat Hin: getName [] ix = Some a
ix < length []
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName (a0 :: k) ix = Some a
ix < length (a0 :: k)
a: atom ix: nat Hin: getName [] ix = Some a
ix < length []
false.
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName (a0 :: k) ix = Some a
ix < length (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k Hin: getName (a0 :: k) 0 = Some a
0 < length (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName (a0 :: k) (S ix) = Some a
S ix < length (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k Hin: getName (a0 :: k) 0 = Some a
0 < length (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k Hin: getName (a0 :: k) 0 = Some a
0 < S (length k)
lia.
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName (a0 :: k) (S ix) = Some a
S ix < length (a0 :: k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName (a0 :: k) (S ix) = Some a
S ix < S (length k)
a0: atom k: list atom a: atom IHk: forallix : nat, getName k ix = Some a -> ix < length k ix: nat Hin: getName k ix = Some a
S ix < S (length k)
a0: atom k: list atom a: atom ix: nat IHk: ix < length k Hin: getName k ix = Some a
S ix < S (length k)
lia.Qed.
forall (k : key) (ix : nat),
contains_ix_upto ix k ->
{a : atom | getName k ix = Some a}
forall (k : key) (ix : nat),
contains_ix_upto ix k ->
{a : atom | getName k ix = Some a}
forall (k : key) (ix : nat),
ix < length k -> {a : atom | getName k ix = Some a}
k: key ix: nat H: ix < length k
{a : atom | getName k ix = Some a}
ix: nat
forallk : key,
ix < length k -> {a : atom | getName k ix = Some a}
k: key Hlt: 0 < length k
{a : atom | getName k 0 = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} k: key Hlt: S ix < length k
{a : atom | getName k (S ix) = Some a}
k: key Hlt: 0 < length k
{a : atom | getName k 0 = Some a}
Hlt: 0 < length []
{a : atom | getName [] 0 = Some a}
n: atom k: list atom Hlt: 0 < length (n :: k)
{a : atom | getName (n :: k) 0 = Some a}
Hlt: 0 < length []
{a : atom | getName [] 0 = Some a}
Hlt: 0 < 0
{a : atom | getName [] 0 = Some a}
lia.
n: atom k: list atom Hlt: 0 < length (n :: k)
{a : atom | getName (n :: k) 0 = Some a}
n: atom k: list atom Hlt: 0 < length (n :: k)
{a : atom | Some n = Some a}
eauto.
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} k: key Hlt: S ix < length k
{a : atom | getName k (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} Hlt: S ix < length []
{a : atom | getName [] (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} n: atom k: list atom Hlt: S ix < length (n :: k)
{a : atom | getName (n :: k) (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} Hlt: S ix < length []
{a : atom | getName [] (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} Hlt: S ix < length []
False
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} Hlt: S ix < 0
False
lia.
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} n: atom k: list atom Hlt: S ix < length (n :: k)
{a : atom | getName (n :: k) (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} n: atom k: list atom Hlt: S ix < S (length k)
{a : atom | getName (n :: k) (S ix) = Some a}
ix: nat IHix: forallk : key,
ix < length k ->
{a : atom | getName k ix = Some a} n: atom k: list atom Hlt: S ix < S (length k)
{a : atom | getName k ix = Some a}
ix: nat k: list atom IHix: {a : atom | getName k ix = Some a} n: atom Hlt: S ix < S (length k)
{a : atom | getName k ix = Some a}
assumption.Qed.
forall (k : key) (ix : nat),
contains_ix_upto ix k <->
(existsa : atom, getName k ix = Some a)
forall (k : key) (ix : nat),
contains_ix_upto ix k <->
(existsa : atom, getName k ix = Some a)
k: key ix: nat
contains_ix_upto ix k <->
(existsa : atom, getName k ix = Some a)
k: key ix: nat
contains_ix_upto ix k ->
existsa : atom, getName k ix = Some a
k: key ix: nat
(existsa : atom, getName k ix = Some a) ->
contains_ix_upto ix k
k: key ix: nat
contains_ix_upto ix k ->
existsa : atom, getName k ix = Some a
k: key ix: nat H: {a : atom | getName k ix = Some a}
existsa : atom, getName k ix = Some a
firstorder.
k: key ix: nat
(existsa : atom, getName k ix = Some a) ->
contains_ix_upto ix k
k: key ix: nat a: atom H: getName k ix = Some a
contains_ix_upto ix k
k: key ix: nat a: atom H: getName k ix = Some a
getName k ix = Some ?a
eauto.Qed.
forall (k : key) (ix : nat),
getName k ix = None -> ~ contains_ix_upto ix k
forall (k : key) (ix : nat),
getName k ix = None -> ~ contains_ix_upto ix k
k: key ix: nat Hin: getName k ix = None
~ contains_ix_upto ix k
k: key ix: nat Hin: getName k ix = None
~ ix < length k
k: key
forallix : nat,
getName k ix = None -> ~ ix < length k
ix: nat Hin: getName [] ix = None
~ ix < length []
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName (a :: k) ix = None
~ ix < length (a :: k)
ix: nat Hin: getName [] ix = None
~ ix < length []
ix: nat Hin: getName [] ix = None
~ ix < 0
lia.
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName (a :: k) ix = None
~ ix < length (a :: k)
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k Hin: getName (a :: k) 0 = None
~ 0 < length (a :: k)
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName (a :: k) (S ix) = None
~ S ix < length (a :: k)
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k Hin: getName (a :: k) 0 = None
~ 0 < length (a :: k)
false.
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName (a :: k) (S ix) = None
~ S ix < length (a :: k)
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName (a :: k) (S ix) = None
~ S ix < S (length k)
a: atom k: list atom IHk: forallix : nat, getName k ix = None -> ~ ix < length k ix: nat Hin: getName k ix = None
~ S ix < S (length k)
a: atom k: list atom ix: nat IHk: ~ ix < length k Hin: getName k ix = None
~ S ix < S (length k)
a: atom k: list atom ix: nat IHk: ~ ix < length k Hin: getName k ix = None
S (length k) <= S ix
lia.Qed.
forall (k : key) (ix : nat),
~ contains_ix_upto ix k -> getName k ix = None
forall (k : key) (ix : nat),
~ contains_ix_upto ix k -> getName k ix = None
k: key ix: nat Hin: ~ contains_ix_upto ix k
getName k ix = None
k: key ix: nat Hin: ~ ix < length k
getName k ix = None
k: key
forallix : nat,
~ ix < length k -> getName k ix = None
ix: nat Hin: ~ ix < length []
getName [] ix = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None ix: nat Hin: ~ ix < length (a :: k)
getName (a :: k) ix = None
ix: nat Hin: ~ ix < length []
getName [] ix = None
reflexivity.
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None ix: nat Hin: ~ ix < length (a :: k)
getName (a :: k) ix = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None ix: nat Hin: ~ ix < S (length k)
match ix with
| 0 => Some a
| S ix => getName k ix
end = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None Hin: ~ 0 < S (length k)
Some a = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None ix: nat Hin: ~ S ix < S (length k)
getName k ix = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None Hin: ~ 0 < S (length k)
Some a = None
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None
0 < S (length k)
lia.
a: atom k: list atom IHk: forallix : nat, ~ ix < length k -> getName k ix = None ix: nat Hin: ~ S ix < S (length k)
getName k ix = None
a: atom k: list atom ix: nat IHk: getName k ix = None Hin: ~ S ix < S (length k)
getName k ix = None
assumption.Qed.
forall (k : key) (ix : nat),
~ contains_ix_upto ix k <-> getName k ix = None
forall (k : key) (ix : nat),
~ contains_ix_upto ix k <-> getName k ix = None
intros; split;
auto using key_lookup_ix_None1, key_lookup_ix_None2.Qed.
forall (k : key) (n : nat),
contains_ix_upto n k *
{a : atom | getName k n = Some a} +
{~ contains_ix_upto n k /\ getName k n = None}
forall (k : key) (n : nat),
contains_ix_upto n k *
{a : atom | getName k n = Some a} +
{~ contains_ix_upto n k /\ getName k n = None}
k: key n: nat
contains_ix_upto n k *
{a : atom | getName k n = Some a} +
{~ contains_ix_upto n k /\ getName k n = None}
k: key n: nat c: contains_ix_upto n k
(contains_ix_upto n k *
{a : atom | getName k n = Some a})%type
k: key n: nat n0: ~ contains_ix_upto n k
~ contains_ix_upto n k /\ getName k n = None
k: key n: nat c: contains_ix_upto n k
(contains_ix_upto n k *
{a : atom | getName k n = Some a})%type
k: key n: nat c: contains_ix_upto n k
contains_ix_upto n k
k: key n: nat c: contains_ix_upto n k
{a : atom | getName k n = Some a}
k: key n: nat c: contains_ix_upto n k
contains_ix_upto n k
assumption.
k: key n: nat c: contains_ix_upto n k
{a : atom | getName k n = Some a}
auto using key_lookup_ix_Some2.
k: key n: nat n0: ~ contains_ix_upto n k
~ contains_ix_upto n k /\ getName k n = None
k: key n: nat n0: ~ contains_ix_upto n k
~ contains_ix_upto n k
k: key n: nat n0: ~ contains_ix_upto n k
getName k n = None
k: key n: nat n0: ~ contains_ix_upto n k
~ contains_ix_upto n k
assumption.
k: key n: nat n0: ~ contains_ix_upto n k
getName k n = None
auto using key_lookup_ix_None2.Defined.Ltaclookup_ix_in_key k n :=
leta := fresh"a"inletHcont := fresh"Hcont"inletH_key_lookup := fresh"H_key_lookup"indestruct (key_lookup_ix_decide k n) as
[[Hcont [a H_key_lookup]] | [Hcont H_key_lookup]];
trycontradiction.Tactic Notation"lookup""index"constr(ix) "in""key"constr(k) :=
lookup_ix_in_key k ix.
forall (k : key) (ix : nat),
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
forall (k : key) (ix : nat),
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
k: key ix: nat
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
k: key ix: nat Hcont: contains_ix_upto ix k a: atom H_key_lookup: getName k ix = Some a
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
k: key ix: nat Hcont: ~ contains_ix_upto ix k H_key_lookup: getName k ix = None
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
k: key ix: nat Hcont: contains_ix_upto ix k a: atom H_key_lookup: getName k ix = Some a
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
k: key ix: nat Hcont: contains_ix_upto ix k a: atom H_key_lookup: getName k ix = Some a
contains_ix_upto ix k
intuition.
k: key ix: nat Hcont: ~ contains_ix_upto ix k H_key_lookup: getName k ix = None
contains_ix_upto ix k \/ ~ contains_ix_upto ix k
nowright.Qed.(** ** Properties of <<getName>> *)(******************************************************************************)
forall (a : atom) (k : list atom) (ix : nat),
ix = 0 -> getName (a :: k) ix = Some a
forall (a : atom) (k : list atom) (ix : nat),
ix = 0 -> getName (a :: k) ix = Some a
a: atom k: list atom ix: nat H: ix = 0
getName (a :: k) ix = Some a
a: atom k: list atom
getName (a :: k) 0 = Some a
reflexivity.Qed.
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a ->
foralla' : atom, getName (a' :: k) (S ix) = Some a
forall (k : key) (ix : nat) (a : atom),
getName k ix = Some a ->
foralla' : atom, getName (a' :: k) (S ix) = Some a
k: key ix: nat a: atom H: getName k ix = Some a a': atom
getName (a' :: k) (S ix) = Some a
assumption.Qed.
forall (a'a : atom) (k : list atom) (ix : nat),
getName (a' :: k) ix = Some a ->
ix = 0 /\ a = a' \/
(existsix' : nat,
ix = S ix' /\ getName k ix' = Some a)
forall (a'a : atom) (k : list atom) (ix : nat),
getName (a' :: k) ix = Some a ->
ix = 0 /\ a = a' \/
(existsix' : nat,
ix = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom ix: nat Hin: getName (a' :: k) ix = Some a
ix = 0 /\ a = a' \/
(existsix' : nat,
ix = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom Hin: getName (a' :: k) 0 = Some a
0 = 0 /\ a = a' \/
(existsix' : nat, 0 = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom ix: nat Hin: getName (a' :: k) (S ix) = Some a
S ix = 0 /\ a = a' \/
(existsix' : nat,
S ix = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom Hin: getName (a' :: k) 0 = Some a
0 = 0 /\ a = a' \/
(existsix' : nat, 0 = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom Hin: Some a' = Some a
0 = 0 /\ a = a' \/
(existsix' : nat, 0 = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom Hin: Some a' = Some a H0: a' = a
0 = 0 /\ a = a \/
(existsix' : nat, 0 = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom Hin: Some a' = Some a H0: a' = a
0 = 0 /\ a = a
nowsplit.
a', a: atom k: list atom ix: nat Hin: getName (a' :: k) (S ix) = Some a
S ix = 0 /\ a = a' \/
(existsix' : nat,
S ix = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom ix: nat Hin: getName k ix = Some a
S ix = 0 /\ a = a' \/
(existsix' : nat,
S ix = S ix' /\ getName k ix' = Some a)
a', a: atom k: list atom ix: nat Hin: getName k ix = Some a
existsix' : nat,
S ix = S ix' /\ getName k ix' = Some a
a', a: atom k: list atom ix: nat Hin: getName k ix = Some a
S ix = S ix /\ getName k ix = Some a
split; auto.Qed.
forall (a : atom) (k : key) (ix : nat),
getIndex k a = Some ix -> getName k ix = Some a
forall (a : atom) (k : key) (ix : nat),
getIndex k a = Some ix -> getName k ix = Some a
a: atom k: key ix: nat H: getIndex k a = Some ix
getName k ix = Some a
a: atom k: key
forallix : nat,
getIndex k a = Some ix -> getName k ix = Some a
a: atom ix: nat Hix: getIndex [] a = Some ix
getName [] ix = Some a
a, a0: atom k: list atom IHk: forallix : nat, getIndex k a = Some ix -> getName k ix = Some a ix: nat Hix: getIndex (a0 :: k) a = Some ix
getName (a0 :: k) ix = Some a
a: atom ix: nat Hix: getIndex [] a = Some ix
getName [] ix = Some a
a: atom ix: nat Hix: None = Some ix
None = Some a
inversion Hix.
a, a0: atom k: list atom IHk: forallix : nat, getIndex k a = Some ix -> getName k ix = Some a ix: nat Hix: getIndex (a0 :: k) a = Some ix
getName (a0 :: k) ix = Some a
a, a0: atom k: list atom IHk: forallix : nat, getIndex k a = Some ix -> getName k ix = Some a ix: nat Hix: a = a0 /\ ix = 0 \/
a <> a0 /\ (existsix' : nat, ix = S ix' /\ getIndex k a = Some ix')
getName (a0 :: k) ix = Some a
a0: atom k: list atom IHk: forallix : nat, getIndex k a0 = Some ix -> getName k ix = Some a0
getName (a0 :: k) 0 = Some a0
a, a0: atom k: list atom IHk: forallix : nat, getIndex k a = Some ix -> getName k ix = Some a Hneq: a <> a0 Hix: nat Hlookup: getIndex k a = Some Hix
getName (a0 :: k) (S Hix) = Some a
a0: atom k: list atom IHk: forallix : nat,
getIndex k a0 = Some ix ->
getName k ix = Some a0
getName (a0 :: k) 0 = Some a0
reflexivity.
a, a0: atom k: list atom IHk: forallix : nat,
getIndex k a = Some ix -> getName k ix = Some a Hneq: a <> a0 Hix: nat Hlookup: getIndex k a = Some Hix
getName (a0 :: k) (S Hix) = Some a
a, a0: atom k: list atom IHk: forallix : nat,
getIndex k a = Some ix -> getName k ix = Some a Hneq: a <> a0 Hix: nat Hlookup: getIndex k a = Some Hix
getName k Hix = Some a
auto.Qed.
forall (a : atom) (k : list atom) (ix : nat),
unique k ->
getName k ix = Some a -> getIndex k a = Some ix
forall (a : atom) (k : list atom) (ix : nat),
unique k ->
getName k ix = Some a -> getIndex k a = Some ix
a: atom k: list atom ix: nat Huniq: unique k Hix: getName k ix = Some a
getIndex k a = Some ix
a: atom k: list atom Huniq: unique k
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix
a: atom Huniq: unique [] ix: nat Hix: getName [] ix = Some a
getIndex [] a = Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix: getName (a0 :: k) ix = Some a
getIndex (a0 :: k) a = Some ix
a: atom Huniq: unique [] ix: nat Hix: getName [] ix = Some a
getIndex [] a = Some ix
a: atom Huniq: unique [] ix: nat Hix: None = Some a
getIndex [] a = Some ix
inversion Hix.
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix: getName (a0 :: k) ix = Some a
getIndex (a0 :: k) a = Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix: getName (a0 :: k) ix = Some a
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix: ix = 0 /\ a = a0 \/
(existsix' : nat,
ix = S ix' /\ getName k ix' = Some a)
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix_zero: ix = 0 Heq: a = a0
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix, ix': nat Heq: ix = S ix' Hrest: getName k ix' = Some a
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix: nat Hix_zero: ix = 0 Heq: a = a0
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a0 ->
getIndex k a0 = Some ix
(if a0 == a0 then Some 0else map S (getIndex k a0)) =
Some 0
compare atoms.
a, a0: atom k: list atom Huniq: unique (a0 :: k) IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix, ix': nat Heq: ix = S ix' Hrest: getName k ix' = Some a
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: unique k ->
forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix, ix': nat Heq: ix = S ix' Hrest: getName k ix' = Some a
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a, a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix, ix': nat Heq: ix = S ix' Hrest: getName k ix' = Some a
(if a == a0 then Some 0else map S (getIndex k a)) =
Some ix
a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a0 ->
getIndex k a0 = Some ix ix': nat Hrest: getName k ix' = Some a0 DESTR_EQs: a0 = a0
Some 0 = Some (S ix')
a, a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix': nat Hrest: getName k ix' = Some a DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S (getIndex k a) = Some (S ix')
a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a0 ->
getIndex k a0 = Some ix ix': nat Hrest: getName k ix' = Some a0 DESTR_EQs: a0 = a0
Some 0 = Some (S ix')
a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a0 ->
getIndex k a0 = Some ix ix': nat Hrest: getName k ix' = Some a0 DESTR_EQs: a0 = a0
False
a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a0 ->
getIndex k a0 = Some ix ix': nat Hrest: a0 ∈ k DESTR_EQs: a0 = a0
False
contradiction.
a, a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix': nat Hrest: getName k ix' = Some a DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S (getIndex k a) = Some (S ix')
a, a0: atom k: list atom Hnin: ~ a0 ∈ k Huniq: unique k IHk: forallix : nat,
getName k ix = Some a -> getIndex k a = Some ix ix': nat Hrest: getName k ix' = Some a DESTR_NEQ: a <> a0 DESTR_NEQs: a0 <> a
map S (Some ix') = Some (S ix')
reflexivity.Qed.
forall (a : atom) (k : list atom) (ix : nat),
unique k ->
getName k ix = Some a <-> getIndex k a = Some ix
forall (a : atom) (k : list atom) (ix : nat),
unique k ->
getName k ix = Some a <-> getIndex k a = Some ix
a: atom k: list atom ix: nat H: unique k
getName k ix = Some a <-> getIndex k a = Some ix
split; auto using key_bijection1, key_bijection2.Qed.