Module rs_admissible
Require Import ssreflect ssrbool ssrfun eqtype ssrnat seq div choice fintype.
Require Import finset zmodp ssralg rs_definitions aux_lemmas rs_dvf advf_type.
Set Implicit Arguments.
Unset Strict Implicit.
Import Prenex Implicits.
Section admissible.
Section rs_adm_prop5.
Section sequences_norep.
Fixpoint subseq (
T:
eqType) (
s1 s2 :
seq T) :=
if s2 is y ::
s2'
then if s1 is x ::
s1'
then if (
x \
in s2)
then subseq s1'
s2 else false else true
else s1 == [::].
Lemma subseqtail (
s2 r2:
seq (
seq nat)) :
r2!= [::] ->
subseq s2 (
behead r2) ->
subseq s2 r2.
Proof.
elim H:
s2=>[|
s21 s22 HI];
first by case H1:
r2.
rewrite {1}/
subseq -/
subseq =>
H1.
case H2:
r2 =>[|
r21 r22];
first by move:
H1;
rewrite H2.
case H3: (
behead (
r21 ::
r22))=>[|
r3 r4];
first by done.
case H4: (
s21 \
in r3 ::
r4);
last by done.
rewrite /
subseq -/
subseq -
H3 -
H2 =>
H5;
move: (
HI H1 H5)=> ->.
have ->: (
s21 \
in r2);
last by done.
by move:
H4;
rewrite -
H3 /
behead H2 inE => ->;
rewrite Bool.orb_true_r.
Qed.
Lemma last_last (
k a1:
nat)(
a2:
seq nat):
a2!=[::] ->
last k a2 =
last k (
a1::
a2).
Proof.
by elim: a2.
Qed.
Lemma last_in (
k i:
nat)(
a:
seq nat): (
a!=[::]) -> ((
last k a)=
i) -> (
i \
in a).
Proof.
elim H:
a=>[|
a1 a2 H3];
first by done.
move=>
H5.
case H2:
a2=>[|
a21 a22];
first by rewrite inE /= => ->.
have H6: (
a2!=
nil);
first by rewrite H2.
rewrite -
H2 -(
last_last k a1 H6) =>
H7.
rewrite inE;
apply/
orP;
right;
apply:(
H3 H6 H7).
Qed.
Lemma in_concat (
s1 k:
nat)(
s2:
seq nat): (
s1 \
in s2 ++ [::
k]) = ((
s1 \
in s2) || (
s1 ==
k)).
Proof.
elim H:
s2 =>[|
s21 s22 HH];
first by rewrite inE.
by rewrite mem_cat !
inE.
Qed.
Lemma uniq_last (
n i:
nat)(
s:
seq nat): (
s!=[::]) -> (
n=
last i s) ->
uniq (
n::
s)=
false.
Proof.
elim H:
s=>[|
s1 s2 H1];
first by done.
case H2:
s2=>[|
s21 s22].
move =>
_ -> /=.
by rewrite inE Bool.andb_true_r /=;
apply/
eqP.
rewrite -
H2 =>
H3 H4.
have H5: (
s2!=[::]);
first by rewrite H2.
move: (@
last_last i s1 s2)=>
H6.
move: (
H6 H5)=>
H7;
rewrite -
H7 in H4.
move: (
H1 H5 H4)=>
H8.
rewrite /
uniq.
have ->: (
n \
notin (
s1::
s2)) =
false;
last first.
by rewrite Bool.andb_false_l.
rewrite inE.
have ->: (
n \
in s2);
last first.
by rewrite Bool.orb_true_r.
move:
H4;
move/
eqP;
rewrite eq_sym;
move/
eqP=>
H4.
by rewrite (
last_in H5 H4).
Qed.
Lemma subseq_norep_seq (
s:
seq nat)(
rest:
seq (
seq nat)):
subseq [::
s]
rest ->
norep rest ->
uniq s.
Proof.
elim H:
rest=>[|
r1 r2 HI];
first by done.
move=>
H1 H2.
have H3: (
norep r2).
case H3:
r2=>[|
r21 r22];
first by done.
move:
H2;
rewrite /
norep /=.
by move/
andP=> [
_ H4];
move:
H4;
rewrite H3 /=.
move:
H1;
rewrite /=.
case H4:(
s \
in r1 ::
r2);
last by done.
move:
H4;
rewrite inE;
move/
orP =>[
H5|
H6]
_.
move: (
eqP H5)=> ->.
move:
H2;
rewrite /=.
by move/
andP=> [->
_].
have H7: (
subseq [::
s]
r2).
rewrite /=.
case H7:
r2=>[|
r21 r22];
first by move:
H6;
rewrite H7.
by rewrite -
H7 H6.
by apply:(
HI H7 H3).
Qed.
Lemma norepik (
i k:
nat):
i !=
k ->
norep [:: [::
i,
k & [::]]].
Proof.
by rewrite /=
inE=> ->.
Qed.
Lemma noreprev (
k:
nat)(
s:
seq nat):
norep [::
s] -> (
k\
in s)=
false ->
norep ([::
s ++ [::
k]]) =
norep ((
k::
s)::[::]).
Proof.
Lemma norep_cat (
r1 r2:
seq (
seq nat)):
norep (
r1 ++
r2) =
norep r1 &&
norep r2.
Proof.
Lemma norephead (
s1:
seq nat)(
s2:
seq (
seq nat)):
norep(
s1::
s2) ->
norep [::
s1].
Proof.
by rewrite /=;
case H: (
uniq s1).
Qed.
Lemma getfirstE_in (
k:
nat)(
s2:
seq nat)(
rest:
seq(
seq nat)):
s2 \
in rest ->
head 0
s2 =
k ->
s2 \
in getfirstE k rest.
Proof.
elim H:
rest => [|
r1 r2 HI];
first by done.
rewrite inE;
move/
orP=> [
H1 |
H2]
H3.
move:(
eqP H1) => <- /=.
move:
H3;
move/
eqP=>
H3;
rewrite H3 inE.
by have H4: ((
s2 ==
s2));
last by rewrite H4.
move: (
HI H2 H3)=>
H4 /=.
by case: (
head 0
r1 ==
k );
first by rewrite inE H4 Bool.orb_true_r.
Qed.
End sequences_norep.
Section getfirst_last.
Lemma getfirstE_headtail (
k:
nat)(
t:
seq nat)(
s:
seq (
seq nat)):
getfirstE k (
t::
s) = ((
getfirstE k (
t::
nil))++ (
getfirstE k s)).
Proof.
Lemma getlastE_headtail (
k:
nat)(
t:
seq nat)(
s:
seq (
seq nat)):
getlastE k (
t::
s) = ((
getlastE k (
t::
nil))++ (
getlastE k s)).
Proof.
rewrite /
getlastE /=.
case H: (
last 0
t ==
k);
first by rewrite cat1s.
by rewrite cat0s.
Qed.
Lemma getfirstEnil (
k:
nat)(
t:
seq nat)(
s:
seq (
seq nat)):
getfirstE k (
t::
s) = [::] -> ((
getfirstE k s)=[::]).
Proof.
elim H:
t=>[|
t1 s1];
first by rewrite /=;
case: (
last 0 [::]==
k).
by rewrite /=;
case: (
head 0 (
t1 ::
s1) ==
k).
Qed.
Lemma getlastEnil (
k:
nat)(
t:
seq nat)(
s:
seq (
seq nat)):
getlastE k (
t::
s) = [::] -> ((
getlastE k s)=[::]) .
Proof.
elim H:t=>[|t1 s1]; first by rewrite /=; case: (last 0 [::]==k).
by rewrite /=; case: (last 0 (t1 :: s1) == k).
Qed.
Lemma in_getfirstE (
k:
nat)(
s1:
seq nat)(
s:
seq (
seq nat)):
s1 \
in s ->
head 0
s1 =
k ->
getfirstE k s!= [::].
Proof.
Lemma in_getlastE (
k:
nat)(
s1:
seq nat)(
s:
seq (
seq nat)):
s1 \
in s ->
last 0
s1 =
k ->
getlastE k s!= [::].
Proof.
elim H:
s=>[|
s2 s3 HI];
first by done.
rewrite inE.
move/
orP=>[
H1|
H1].
move:(
eqP H1) => ->.
rewrite /
getlastE -/
getlastE /=.
by move/
eqP => ->.
move=>
H2.
move:(
HI H1 H2);
rewrite getlastE_headtail =>
H3.
by case H4:(
getlastE k [::
s2])=>[|
l1 l2];
first by rewrite H3.
Qed.
Lemma ingetlastE_last (
i:
nat)(
x:
seq nat)(
rest:
seq (
seq nat)):
x \
in getlastE i rest ->
last 0
x =
i.
Proof.
elim H:
rest =>[|
r1 r2 HI];
first by done.
rewrite /=.
case H1: (
last 0
r1 ==
i);
last by apply:
HI.
rewrite inE;
move/
orP=>[
H2 |
H2];
last by apply:
HI.
by move: (
eqP H2) => ->;
apply/
eqP;
rewrite H1.
Qed.
Lemma ingetfirst (
i:
nat)(
x:
seq nat)(
rest:
seq (
seq nat)):
x \
in getfirstE i rest ->
head 0
x =
i.
Proof.
elim H:
rest =>[|
r1 r2 HI];
first by done.
rewrite /=.
case H1: (
head 0
r1 ==
i);
last by apply:
HI.
rewrite inE;
move/
orP=>[
H2 |
H2];
last by apply:
HI.
by move: (
eqP H2) => ->;
apply/
eqP;
rewrite H1.
Qed.
Lemma subseq_subseqgetfirstE (
k:
nat)(
s2 rest :
seq (
seq nat)):
(
subseq s2 rest) ->
subseq (
getfirstE k s2) (
getfirstE k rest).
Proof.
Lemma ingetlastE (
k:
nat)(
s2:
seq nat)(
rest:
seq(
seq nat)):
s2 \
in rest ->
last 0
s2 =
k ->
s2 \
in getlastE k rest.
Proof.
elim H:
rest => [|
r1 r2 HI];
first by done.
rewrite inE;
move/
orP=> [
H1 |
H2]
H3.
move:(
eqP H1) => <- /=.
move:
H3;
move/
eqP=>->;
rewrite inE.
by have ->: ((
s2 ==
s2)).
move: (
HI H2 H3)=>
H4 /=.
by case: (
last 0
r1 ==
k);
first by rewrite inE H4 Bool.orb_true_r.
Qed.
Lemma subseq_subseqgetlastE (
k:
nat)(
s2 rest :
seq (
seq nat)):
(
subseq s2 rest) ->
subseq (
getlastE k s2) (
getlastE k rest).
Proof.
elim H:
s2=>[|
s21 s22 HI];
first by rewrite /=;
first case: (
getlastE k rest).
rewrite {1}/
subseq -/
subseq.
case H1:
rest=>[|
r1 r2];
first by move/
eqP.
case H2: (
s21 \
in r1 ::
r2);
last by done.
rewrite -
H1=>
H3;
move:(
HI H3)=>
H4;
rewrite /
getlastE -/
getlastE /=.
case H5:(
last 0
s21 ==
k);
last by done.
case H6:((
filter [
pred s |
last 0
s ==
k]
rest)) =>[|
c1 c2];
last first.
rewrite /
subseq -/
subseq.
move:(
eqP H5)=>
H51.
move: (
ingetlastE H2 H51).
rewrite /
getlastE -
H1 H6 => ->.
by move:
H4;
rewrite /
getlastE H6.
rewrite -
H1 in H2.
by move:(
eqP H5) =>
H51;
move: (
in_getlastE H2 H51);
rewrite /
getlastE H6;
move/
eqP.
Qed.
Lemma subseq_concat (
a b rest:
seq (
seq nat)):
subseq (
a++
b)
rest =
subseq a rest &&
subseq b rest.
Proof.
case H: rest =>[|r1 r2]; first by elim: a.
elim H1: a=>[|a1 a2 HI]; first by done.
rewrite /=.
by case H2:(a1 \in r1 :: r2); first by rewrite HI.
Qed.
Lemma inseq (
i a1:
seq nat)(
a2:
seq (
seq nat)):
i \
in a2 ->
i \
in (
a1::
a2).
Proof.
Lemma insubseq (
s:
seq nat)(
r:
seq (
seq nat)):
s \
in r ->
subseq [::
s]
r.
Proof.
elim H:
r=>[|
r1 r2 HI];
first by done.
rewrite inE;
move/
orP=>[
H1|
H1].
move:(
eqP H1) => <- /=.
by have ->: (
s \
in s ::
r2);
first by rewrite inE;
apply/
orP;
left.
move: (
HI H1)=>
H3.
by have H4: (
r1::
r2!=[::]);
last by apply: (
subseqtail H4 H3).
Qed.
Lemma subseq_behead (
r:
seq (
seq nat)):
subseq (
behead r)
r.
Proof.
elim H:
r=>[|
r1 r2 HI];
first by done.
case H1:
r2=>[|
r21 r22];
first by done.
rewrite /=.
have ->: (
r21 \
in [::
r1,
r21 &
r22]);
first by rewrite !
inE;
apply/
orP;
right;
apply/
orP;
left.
rewrite H1 /
behead in HI.
by have H2: ([::
r1,
r21 &
r22]!=[::]);
last by apply:(
subseqtail H2 HI).
Qed.
Lemma subseq_getfirstE (
k:
nat)(
rest:
seq (
seq nat)):
(
subseq (
getfirstE k rest)
rest).
Proof.
elim H:
rest =>[|
r1 r2 HI];
first by done.
rewrite /
getfirstE -/
getfirstE.
have H2: (
r1::
r2!=[::]);
first by done.
move: (
subseqtail H2 HI)=>
H3 /=.
case H1: (
head 0
r1 ==
k);
last by rewrite H3.
rewrite /
subseq -/
subseq inE //=.
have -> :
r1 ==
r1;
first by done.
by move:
H3;
rewrite /= /
getfirstE.
Qed.
Lemma subseq_getlastE (
i:
nat)(
rest:
seq (
seq nat)): (
subseq (
getlastE i rest)
rest).
Proof.
elim H:
rest =>[|
r1 r2 HI];
first by done.
rewrite /
getlastE -/
getlastE.
have H2: (
r1::
r2!=[::]);
first by done.
move: (
subseqtail H2 HI)=>
H3 /=.
case H1: (
last 0
r1 ==
i);
last by rewrite H3.
rewrite /
subseq -/
subseq inE //=.
have -> :
r1 ==
r1;
first by done.
by move:
H3;
rewrite /= /
getlastE.
Qed.
End getfirst_last.
Section canAddOrder.
Lemma norepAddOrders (
i k:
nat)(
s:
seqZ2):
i!=
k ->
s!= [::]
->((
head false s) !=
false) ->
canAddOrders i k s [::] ->
norep (
addOrders i k s [::]) =
norep (
addOrders i (
k+1) (
behead s) ((
i::
k::
nil)::
nil)).
Proof.
move=>
H2.
elim H8:
s=>[|
s21 s22 HH];
first by done.
move=>
H3 H4 H5 /=.
case H6:
s22=>[|
s3 s4];
last by rewrite /
head in H4;
rewrite H2 H4.
by rewrite /
head in H4;
rewrite H2 H4 /
addOrders /=.
Qed.
Lemma canAddOrder_tail (
i k:
nat)(
a:
seq nat)(
rest:
seq (
seq nat)):
(
i!=
k) ->
uniq a ->
(
canAddOrder i k (
a ::
rest)) -> (
canAddOrder i k rest).
Proof.
move=>
H H4 /=.
elim H5:
rest=>[|
r1 r2 HH];
first by rewrite /=
H.
by case H6:
r2;
case:(
nocycles_order i k a ==
true);
rewrite H.
Qed.
Lemma last_possize (
s:
seq nat):
uniq s ->
s!=[::] -> ((
index (
last 0
s)
s) = (
size s) - 1).
Proof.
elim H:
s=>[|
s1 s2];
first by done.
move=>
HI H1 H2.
have H3: (
uniq s2).
by move:
H1;
rewrite /
uniq -/
uniq;
move/
andP=>[
_ ->].
case H4: (
s2==[::]).
rewrite (
eqP H4) /=.
by have ->: (
s1 ==
s1).
move:
H4;
move/
eqP;
move/
eqP.
move=>
H6;
move: (
HI H3 H6) =>
H7.
rewrite /=.
case H8:(
s1 ==
last s1 s2).
move:
H8;
move/
eqP;
case H9:
s2=>[|
s21 s22];
first by done.
rewrite -
H9 =>
H10.
by move:
H1;
rewrite (
uniq_last H6 H10).
move:
H6 H7;
case H9:
s2=>[|
s21 s22];
first by done.
move=>
H6;
rewrite /= => ->.
by rewrite !
subn1 /=.
Qed.
Lemma norepAddOrder_order_head (
i k:
nat)(
d1:
seq nat)(
d2:
seq (
seq nat)):
i !=
k ->
norep (
d1::
d2) ->
canAddOrder i k (
d1::
d2) ->
norep (
addOrder_order i k d1) =
true.
Proof.
move =>
H2 H4.
rewrite /=
H2.
case H6: (
nocycles_order i k d1 ==
true);
last by move:
H4.
rewrite /
addOrder_order =>
_.
case H9:
d1=>[|
d11 d12];
first by done.
move:
H6;
rewrite /
nocycles_order H9.
have ik: (
i==
k)=
false;
first by apply/
eqP;
apply/
eqP.
case H10:
d12=>[|
d31 d32].
case H11: (
i ==
last 0 [::
d11]).
case H12:(
k ==
head 0 [::
d11]);
first by done.
move:
H11;
rewrite /=;
move/
eqP => <-.
by rewrite !
inE /= (
eq_sym k _)
ik.
case H12: (
k ==
head 0 [::
d11]);
last by done.
move:
H12;
rewrite /=;
move/
eqP => <-.
by rewrite !
inE /= (
eq_sym k _)
ik.
case H13:((
i \
in [::
d11,
d31 &
d32]) ==
false).
case H14:(
i ==
last 0 [::
d11,
d31 &
d32]).
have H15: ([::
d11,
d31 &
d32]!=[::]);
first by done.
have H16: (
last 0 [::
d11,
d31 &
d32] =
i);
first by move:
H14;
move/
eqP => ->.
move: (
last_in H15 H16).
by have ->: (
i \
in [::
d11,
d31 &
d32])=
false;
first by move:
H13;
move/
eqP.
case H15:(
k ==
head 0 [::
d11,
d31 &
d32]);
last by done.
rewrite /
norep.
have: (
all uniq ([:: [::
i] ++ [::
d11,
d31 &
d32]]));
last by move=> ->.
move: (
eqP H15) => /=
H151.
have H16: (
i ==
d11)=
false;
first by rewrite -
H151;
apply/
eqP;
apply/
eqP.
rewrite inE H16.
have H17: (
i==
d31)=
false.
move:(
eqP H13);
rewrite !
inE H16.
move: (@
Bool.orb_false_elim (
i ==
d31)(
i \
in d32)) =>
H17 H18.
by move: (
H17 H18);
move=>[
H19 H20].
rewrite !
inE H17.
have H18: (
d11 ==
d31)=
false;
last first.
move:
H13;
rewrite H18 inE H16 Bool.orb_false_l inE H17 Bool.orb_false_l;
move/
eqP =>
H19.
case H20:
d32=>[|
d221 d222];
first by rewrite /=.
rewrite -
H20.
rewrite H19 /=.
move:
H4;
rewrite H9 H10 /
norep.
case H23: (
all uniq ([::
d11,
d31 &
d32] ::
d2));
last by done.
move:
H23;
rewrite /=.
rewrite !
inE.
move/
andP =>[
H21 H22].
move:
H21;
move/
andP=> [
H21 H23];
move:
H23;
move/
andP=> [
H23 H24].
move:
H21;
rewrite Bool.negb_orb;
move/
andP=> [
_ ->].
by rewrite H23 H24.
move:
H4;
rewrite H9 H10 /=.
case H18:(
d11 \
notin d31 ::
d32);
last by done.
move:
H18;
rewrite inE Bool.negb_orb.
move/
andP=>[
H18 _]
_.
by apply/
eqP;
apply/
eqP.
case H14:((
k \
in [::
d11,
d31 &
d32]) ==
false).
case H15:(
i ==
last 0 [::
d11,
d31 &
d32]).
case H16:(
k ==
head 0 [::
d11,
d31 &
d32]).
move: (
eqP H16);
rewrite /
head =>
H161.
move:
H14;
rewrite H161 inE;
move/
eqP.
move: (@
Bool.orb_false_elim (
d11 ==
d11)(
d11 \
in d31 ::
d32)) =>
H17 H18.
by move:(
H17 H18) => [
H19 H20].
rewrite -
H10 -
H9 noreprev /
norep.
have ->: (
all uniq [::
k ::
d1]);
last by done.
rewrite /=;
move: (
eqP H14);
rewrite -
H10 -
H9 =>
H141.
move:
H4;
rewrite /
norep /=;
move/
andP=>[->
_].
rewrite !
Bool.andb_true_r.
by move:
H141;
rewrite H9 inE => ->.
apply:(
norephead H4).
case H17:(
k ==
head 0 [::
d11,
d31 &
d32]);
first by move:
H16;
rewrite H17.
by move: (
eqP H14);
rewrite -
H10 -
H9.
case H16:(
k ==
head 0 [::
d11,
d31 &
d32]);
last by done.
move: (
eqP H16);
rewrite /
head =>
H161.
move: (
eqP H14);
rewrite H161 inE =>
H17.
move: (@
Bool.orb_false_elim (
d11 ==
d11)(
d11 \
in d31 ::
d32)
H17) => [
H18 H19].
by move:
H18;
move/
eqP.
case H15: (
index i [::
d11,
d31 &
d32] <
index k [::
d11,
d31 &
d32]);
last by done.
case H16:(
i ==
last 0 [::
d11,
d31 &
d32]).
have H17: (
uniq [::
d11,
d31 &
d32]).
by move:
H4;
rewrite H9 H10 /
norep /=;
move/
andP=>[->
_].
have H25: ([::
d11,
d31 &
d32]!=[::]);
first by done.
move: (
last_possize H17 H25) =>
hh.
move:
H13;
case H13: ((
i \
in [::
d11,
d31 &
d32]));
last by done.
move:
H14;
case H14: ((
k \
in [::
d11,
d31 &
d32]));
last by done.
move: (
index_mem i [::
d11,
d31 &
d32])=>
h15.
move: (
index_mem k [::
d11,
d31 &
d32])=>
h16.
rewrite -
h16 in H14;
rewrite -
h15 in H13.
move:
H15;
rewrite (
eqP H16)
hh;
move:
H14.
case hh1 :(
size [::
d11,
d31 &
d32])=> [|
n];
first by done.
rewrite subn1 ltnS.
have -> : (
n.+1.-1 =
n);
first by done.
move=>
H15 H161.
by move: (
leq_ltn_trans H15 H161);
rewrite ltnn.
case H17:(
k ==
head 0 [::
d11,
d31 &
d32]);
last by done.
have H22: ([::
d11,
d31 &
d32] !=[::]);
first by done.
move:
H17;
move/
eqP;
rewrite /
head=>
H23.
move:
H15;
rewrite H23 /=.
have -> : (
d11 ==
d11);
first by done.
case H24: (
index i [::
d11,
d31 &
d32]) =>[|
n];
last first.
by case H25:
n;
first by done.
have H21: (
i \
in [::
d11,
d31 &
d32]);
first by move:
H13;
move/
eqP;
case:((
i \
in [::
d11,
d31 &
d32])).
have H25: (
uniq [::
d11,
d31 &
d32]).
move:
H4;
rewrite -
H10 -
H9.
by rewrite /
norep /=;
move /
andP =>[->
_].
case H26:(
d11==
i);
first by done.
by case h27: (
d31==
i);
first by done.
Qed.
Lemma canAddOrder_norep (
i k:
nat)(
d:
seq (
seq nat)):
i !=
k ->
norep d->
canAddOrder i k d ->
norep (
addOrder_orders i k d).
Proof.
Lemma canAddOrder_nocycles (
i k:
nat)(
s1:
seq nat)(
rest:
seq (
seq nat)):
i!=
k ->
rest !=[::] ->
s1 \
in rest ->
canAddOrder i k rest ->
nocycles_order i k s1.
Proof.
move=>
H4.
elim H:
rest =>[|
r1 r2 HI];
first by done.
case H1:
r2=>[|
r21 r22].
move=>
H2;
rewrite inE /=
H4;
move/
eqP=> ->.
by case:(
nocycles_order i k r1).
move=>
H2 H3 H5.
have H6: (
r2!=[::]);
first by rewrite H1.
move:
H3;
rewrite inE;
move/
orP=>[
H71 |
H72].
move:
H71 H5;
move/
eqP => <-.
rewrite /=
H4.
by case H8:(
nocycles_order i k s1 ==
true);
first by move: (
eqP H8).
rewrite -
H1 in H72.
have H8: (
canAddOrder i k r2);
last by apply: (
HI H6 H72 H8).
move:
H5;
rewrite /=
H4.
case H8:(
nocycles_order i k r1 ==
true);
last by done.
case H9:
r22=>[|
r3 r4];
first by rewrite H1 H9 /=
H4.
case H10:(
nocycles_order i k r21 ==
true);
last by done.
by rewrite -
H9 H1 /=
H4 H10.
Qed.
Lemma subseq_canAddOrder (
i k:
nat)(
s2 rest:
seq (
seq nat)):
i!=
k ->
norep rest ->
subseq s2 rest ->
canAddOrder i k rest ->
canAddOrder i k s2.
Proof.
move=>
H.
elim H1:
s2=> [|
s21 s22 HI];
first by rewrite /=
H.
move=>
H2 H3 H4.
case H5: (
subseq s22 rest);
last first.
move:
H3=> /=.
case H6:
rest =>[|
r1 r2];
first by done.
case H7:(
s21 \
in r1 ::
r2);
last by done.
by rewrite -
H6 H5.
move:(
HI H2 H5 H4) =>
H6.
rewrite /=
H6 H.
have ->: (
nocycles_order i k s21 ==
true);
last by done.
move:
H3 => /=.
case H7:
rest=>[|
r1 r2];
first by done.
case H8:(
s21 \
in r1 ::
r2);
last by done.
move=>
H9;
rewrite H7 in H4.
by have H10: (
r1 ::
r2)!=[::];
last by move: (
canAddOrder_nocycles H H10 H8 H4)=> ->.
Qed.
End canAddOrder.
Section canAOrder.
Lemma in_nocycles_concat (
s:
seq nat) (
rest lasts:
seq (
seq nat)):
s \
in rest ->
nocycles_concat_orders rest lasts ->
nocycles_concat_order s lasts.
Proof.
Lemma subseq_nocycles (
s rest lasts:
seq (
seq nat)):
subseq s rest ->
nocycles_concat_orders rest lasts ->
nocycles_concat_orders s lasts.
Proof.
elim H:
s=>[|
s1 s2 HI];
first by rewrite /=.
rewrite /
subseq -/
subseq.
case H1:
rest =>[|
r1 r2];
first by rewrite /=.
case H2: (
s1 \
in r1 ::
r2);
last by done.
rewrite -
H1=>
H3 H4;
move: (
HI H3 H4)=>
H5.
rewrite /
nocycles_concat_orders -/
nocycles_concat_orders.
case H7:
lasts =>[|
l1 l2];
first by done.
rewrite -
H7 H5;
rewrite -
H1 in H2.
by move:(
in_nocycles_concat H2 H4) => ->.
Qed.
Lemma nocycles_headtail (
s1:
seq nat)(
firsts s2:
seq (
seq nat)):
nocycles_concat_orders firsts (
s1::
s2) =
nocycles_concat_orders firsts [::
s1] &&
nocycles_concat_orders firsts s2.
Proof.
Lemma in_nocycles (
s1:
seq nat)(
firsts rest :
seq (
seq nat)):
s1 \
in rest ->
nocycles_concat_orders firsts rest ->
nocycles_concat_orders firsts [::
s1].
Proof.
Lemma subseq_nocycles2 (
s rest firsts:
seq (
seq nat)):
subseq s rest ->
nocycles_concat_orders firsts rest ->
nocycles_concat_orders firsts s.
Proof.
elim H:
s=>[|
s1 s2 HI];
first by case H1:
firsts =>[|
l1 l2];
last by case l2.
rewrite /
subseq -/
subseq.
case H1:
rest =>[|
r1 r2];
first by done.
case H2: (
s1 \
in r1 ::
r2);
last by done.
rewrite -
H1=>
H3 H4;
move: (
HI H3 H4)=>
H5.
case H6:
firsts =>[|
f1 f2];
first by done.
rewrite nocycles_headtail -
H6 H5 Bool.andb_true_r;
rewrite -
H1 in H2.
apply:(
in_nocycles H2 H4).
Qed.
Lemma nocycles_subseq (
i k:
nat)(
s2 rest:
seq (
seq nat)):
(
i!=
k) ->
subseq s2 rest ->(
nocycles_concat_orders (
getfirstE k rest) (
getlastE i rest)) ->
(
nocycles_concat_orders (
getfirstE k s2) (
getlastE i s2)).
Proof.
Lemma norep_seq_canAOrder (
i k:
nat)(
a:
seq nat)(
rest:
seq (
seq nat)):
(
i!=
k) ->
uniq a ->
(
canAOrder i k (
rest)) -> (
canAOrder i k (
behead rest)).
Proof.
Lemma canAcanAdd_norep (
i k:
nat)(
a c:
seq nat)(
r:
seq (
seq nat)):
i!=
k ->
norep r ->
head 0
a =
k ->
last 0
c =
i ->
subseq [::
a]
r ->
subseq [::
c]
r ->
canAOrder i k r ->
canAddOrder i k r ->
norep [::
c ++
a].
Proof.
move=>
H2 H3 H4 H5 H6 H7 H8 H9.
have H17: (
c==
a)=
false.
case H17:((
c ==
a));
last by done.
move: (
eqP H17) =>
H171;
rewrite H171 in H5.
move: (
subseq_canAddOrder H2 H3 H6 H9).
rewrite /
canAddOrder H2 /
nocycles_order.
case H18:
a=>[|
a11 a12].
move:
H4 H5;
rewrite H18 /==>
H4 H5.
by move:
H2;
rewrite -
H4 -
H5;
move/
eqP.
case H19:
a12;
first by rewrite H19 in H18;
rewrite H18 in H4 H5;
move:
H5 H4 H2;
rewrite /= => -> ->;
move/
eqP.
rewrite -
H19 -
H18.
have H20:
a!=[::];
first by rewrite H18.
move: (
last_in H20 H5)=>
H22.
have H21: (
k \
in a);
first by move:
H4;
rewrite H18 /= => ->;
rewrite inE;
apply/
orP;
left.
rewrite H21 H22 /=.
have H151: (
i =
last 0
a);
first by rewrite H5.
case H15: (
index i a <
index k a);
last by done.
have H1711: (
uniq a);
first by apply:(
subseq_norep_seq H6 H3).
move: (
last_possize H1711 H20) =>
hh.
move: (
index_mem i a)=>
h15.
move: (
index_mem k a)=>
h16.
rewrite -
h16 in H21;
rewrite -
h15 in H22.
move:
H15;
rewrite H151 hh.
move:
H21.
case hh1 :(
size a)=> [|
n];
first by done.
rewrite subn1 ltnS.
have -> : (
n.+1.-1 =
n);
first by done.
move=>
H15 H161.
by move: (
leq_ltn_trans H15 H161);
rewrite ltnn.
move:
H3 H6 H7 H8 H9.
elim H10:
r=>[|
r1 r2 HI];
first by done.
rewrite /
subseq =>
HH.
case H3:(
a \
in r1 ::
r2);
last by done.
move:
H3;
rewrite inE;
move/
orP=>[
H41 |
H41]
_.
case H51:(
c \
in r1 ::
r2);
last by done.
move:
H51;
rewrite inE;
move/
orP=>[
H6|
H7].
by move:
H4;
move/
eqP=>
H4;
move: (
eqP H41)=>
H411;
move:
H17;
rewrite H411 H6;
move/
eqP.
move: (
eqP H41) => <-;
rewrite /
canAOrder.
have ->:((
getfirstE k (
a ::
r2) == [::]) || (
getlastE i (
a ::
r2) == [::])=
false);
last first.
have: (
a \
in (
getfirstE k (
a ::
r2)));
first by rewrite /=
H4;
have ->:(
k==
k);
last by rewrite inE;
apply/
orP;
left.
move=>
H8 _ H9.
move: (
in_nocycles_concat H8 H9).
have H71:
c\
in (
a::
r2);
first by apply: (
inseq a H7).
move: (
ingetlastE H71 H5)=>
H11 H12 H13;
move: (
insubseq H11) =>
H14.
move: (
subseq_nocycles2 H14 H9)=>
H91.
have H81: (
a \
in (
getfirstE k (
a ::
r2)));
first by rewrite /=
H4;
have ->:(
k==
k);
last by rewrite inE;
apply/
orP;
left.
move: (
in_nocycles_concat H81 H91)=> /=.
case H15:
a=>[|
a1 a2].
rewrite cats0.
have hh: (
norep r2).
by move:
HH;
rewrite /=;
move/
andP=>[
_ H16];
move:
H16;
case ff :
r2.
move: (
insubseq H7)=>
H6.
by rewrite (
subseq_norep_seq H6 hh).
rewrite -
H15 /
norep.
by case : (
uniq (
c ++
a)).
rewrite /=
H4 -/
getfirstE.
have ->: (
k==
k);
first by rewrite /=.
have ->: ((
getlastE i (
a ::
r2) == [::]) =
false);
last by done.
have H71:
c\
in (
a::
r2);
first by apply: (
inseq a H7).
move: (
ingetlastE H71 H5).
by case H11:(
getlastE i (
a ::
r2)).
case H51:(
c \
in r1 ::
r2);
last by done.
move:
H51;
rewrite inE;
move/
orP=>[
H6|
H7]
_;
last first.
move: (
insubseq H7)(
insubseq H41)=>
H9 H8 H12 H13.
have H11: (
norep r2).
case H:
r2=>[|
r21 r22];
first by done.
move:
HH;
rewrite /= /
norep H /=
Bool.andb_comm.
by move/
andP=>[->
_].
have H14: (
uniq r1).
by move:
HH;
rewrite /=;
move/
andP=>[->
_].
move: (
canAddOrder_tail H2 H14 H13)=>
H18.
move: (
norep_seq_canAOrder H2 H14 H12)=>
H19.
apply: (
HI H11 H8 H9 H19 H18).
move: (
eqP H6) => <-;
rewrite /
canAOrder /
canAddOrder -/
canAddOrder.
have ->:((
getfirstE k (
c ::
r2) == [::]) || (
getlastE i (
c ::
r2) == [::])=
false);
last first.
have H8: (
c \
in (
getlastE i (
c ::
r2)));
first by rewrite /=
H5;
have ->:(
i==
i);
last by rewrite inE;
apply/
orP;
left.
move: (
insubseq H8) =>
H14 H9 _.
move: (
subseq_nocycles2 H14 H9).
have H71:
a\
in (
c::
r2);
first by apply: (
inseq c H41).
move: (
getfirstE_in H71 H4)=>
H12.
move: (
insubseq H12) =>
H15 H16.
move: (
subseq_nocycles H15 H16);
rewrite /=.
case H151:
a=>[|
a1 a2].
rewrite cats0.
by have ->: (
uniq c);
first by move:
HH;
rewrite /= -(
eqP H6);
move/
andP=>[->
_].
by case:(
uniq (
c ++
a1 ::
a2)).
rewrite /=
H5.
have ->: (
i==
i);
first by done.
have ->: ((
getfirstE k (
c ::
r2) == [::]) =
false);
last by done.
have H71:
a\
in (
c::
r2);
first by apply: (
inseq c H41).
move: (
getfirstE_in H71 H4).
by case H11:(
getfirstE k (
c ::
r2)).
Qed.
Lemma norep_addOrder_concat (
i k:
nat)(
r:
orders)(
rest:
orders *
orders):
(
i !=
k) ->
norep r ->
(
forall x:
seq nat,
x \
in (
fst rest) ->
head 0
x =
k) ->
(
forall x:
seq nat,
x \
in (
snd rest) ->
last 0
x =
i) ->
subseq (
fst rest)
r ->
subseq (
snd rest)
r ->
canAddOrder i k r ->
canAOrder i k r ->
norep (
addOrder_concat rest).
move=>
H3.
functional induction addOrder_concat rest.
by done.
by done.
rewrite /
fst /
snd in IHo.
rewrite e e0 =>
H5 H6 H7 H11.
have H10: (
forall x :
seq nat,
x \
in d ->
last 0
x =
i).
by move=>
x H;
move: (
H7 x);
rewrite inE H Bool.orb_true_r => ->.
rewrite /
subseq -/
subseq.
case H12:
r=> [|
r1 r2];
first by done.
rewrite H12 in IHo H5 H11.
case H13:(
c \
in (
r1::
r2));
last by done.
rewrite norep_cat =>
H14 H15 H16.
move: (
IHo H5 H6 H10 H11 H14 H15 H16) => ->.
have HH2: (
a \
in [::
a]);
first by rewrite inE.
have HH3: (
c \
in c::
d);
first by rewrite inE;
apply/
orP;
left.
move: (
H7 c HH3) =>
H17.
move: (
H6 a HH2)=>
H18.
have H19: (
subseq [::
c] (
r1::
r2));
first by rewrite /
subseq H13.
by rewrite (
canAcanAdd_norep H3 H5 H18 H17 H11 H19 H16 H15).
rewrite /
fst /
snd in IHo.
rewrite e e0 {1}/
subseq -/
subseq norep_cat =>
H5 H6 H7.
case H12:
r=> [|
r1 r2];
first by done.
case H13: (
a \
in r1 ::
r2);
last by done.
rewrite H12 in IHo H5 =>
H11 H14 H15 H16.
have H10:(
forall x :
seq nat,
x \
in b ->
head 0
x =
k).
by move=>
x H;
move: (
H6 x);
rewrite inE H Bool.orb_true_r => ->.
move: (
IHo H5 H10 H7 H11 H14 H15 H16) => ->.
have HH3: (
c \
in [::
c]);
first by rewrite inE.
have HH2: (
a \
in a::
b);
first by rewrite inE;
apply/
orP;
left.
move: (
H7 c HH3) =>
H17.
move: (
H6 a HH2)=>
H18.
have H19: (
subseq [::
a] (
r1::
r2));
first by rewrite /
subseq H13.
by rewrite (
canAcanAdd_norep H3 H5 H18 H17 H19 H14 H16 H15).
rewrite /
fst /
snd in IHo IHo0.
rewrite e e0 {1}/
subseq -/
subseq !
norep_cat =>
H5 H6 H7.
case H12:
r=> [|
r1 r2];
first by done.
case H13: (
a \
in r1 ::
r2);
last by done.
rewrite H12 in IHo H5 IHo0 =>
H15 H16 H17 H18.
have H10:(
forall x :
seq nat,
x \
in b ->
head 0
x =
k).
by move=>
x H;
move: (
H6 x);
rewrite inE H Bool.orb_true_r => ->.
move: (
IHo0 H5 H10 H7 H15 H16 H17 H18) => ->.
have H19:(
forall x :
seq nat,
x \
in [::
a] ->
head 0
x =
k).
by move=>
x;
rewrite inE =>
H;
move: (
H6 x);
rewrite inE H Bool.orb_true_l => ->.
have H20:(
forall x :
seq nat,
x \
in d ->
last 0
x =
i).
by move=>
x H;
move: (
H7 x);
rewrite inE H Bool.orb_true_r => ->.
have H21: (
subseq [::
a] (
r1::
r2));
first by rewrite /
subseq H13.
move:
H16;
rewrite /
subseq -/
subseq.
case H22:(
c \
in r1 ::
r2);
last by done.
move=>
H23.
move: (
IHo H5 H19 H20 H21 H23 H17 H18) => ->.
have HH2: (
a \
in a::
b);
first by rewrite inE;
apply/
orP;
left.
have HH3: (
c \
in c::
d);
first by rewrite inE;
apply/
orP;
left.
move: (
H7 c HH3) =>
H24.
move: (
H6 a HH2)=>
H25.
have H26: (
subseq [::
c] (
r1::
r2));
first by rewrite /
subseq H22.
by rewrite (
canAcanAdd_norep H3 H5 H25 H24 H21 H26 H18 H17).
Qed.
End canAOrder.
Section canAddOrders.
Lemma canAddOrders_tail (i k :nat) (a: bool)(x: seqZ2)(s: orders):
(i != k) && (a != false) = false -> x!=[::] -> canAddOrders i k (a::x) s =
canAddOrders i (k+1) x s.
Proof.
rewrite /= => -> H1.
case H2: x; first by move:H1; rewrite H2.
by case: s.
Qed.
Lemma canAddOrders_tailnil (i k:nat)(s:seqZ2):
i != k -> (head false s) != false -> s!=[::] ->
canAddOrders i k s [::] -> canAddOrders i (k + 1) (behead s) ((i::k::nil)::nil).
Proof.
elim H3:
s=>[|
s1 s2 HH];
first by done.
move=>
H2 H4 H5.
rewrite /
head in H4;
rewrite /=
H2 H4.
by case H6:
s2.
Qed.
Lemma canAddOrders_addOrders (i j:nat)(col: seqZ2) (d: orders):
norep d -> canAddOrders i j col d -> norep (addOrders i j col d) = true.
Proof.
move=>
H2 H3.
functional induction (
addOrders i j col d);
try by move => //=.
by move:(
andP e2)=>[
H4 H5];
apply:
norepik.
move: (
andP e2) => [
H5 H6];
rewrite norep_cat.
move: (
norepik H6)=> ->.
move:
H3;
rewrite /
canAddOrders H5 H6.
case H7: (
canAddOrder i k (
_x ::
_x0) &&
canAOrder i k (
_x ::
_x0));
last by done.
move: (
andP H7) =>[
H31 H32] =>
_.
by apply: (
canAddOrder_norep H6 H2 H31).
move: (
andP e2) => [
H5 H6];
rewrite norep_cat.
move: (
norepik H6)=> ->.
move:
H3;
rewrite /
canAddOrders H5 H6;
move/
andP=>[
H31 _];
move: (
andP H31)=>[
H311 H32].
rewrite norep_cat (
canAddOrder_norep H6 H2 H311).
move: (
subseq_getfirstE k (
_x ::
_x0))(
subseq_getlastE i (
_x ::
_x0))=>
HH1 HH2.
have H7:(
forall x :
seq nat,
x \
in ((
getfirstE k (
_x ::
_x0),
getlastE i (
_x ::
_x0)).1) ->
head 0
x =
k).
by rewrite /
fst =>
x H4;
apply: (
ingetfirst H4).
have H8:(
forall x :
seq nat,
x \
in ((
getfirstE k (
_x ::
_x0),
getlastE i (
_x ::
_x0)).2) ->
last 0
x =
i).
by rewrite /
snd =>
x H4;
apply: (
ingetlastE_last H4).
by move: (
norep_addOrder_concat H6 H2 H7 H8 HH1 HH2 H311 H32).
have H4: (
k + 1 == 0) =
false;
first by rewrite addn1.
move:(
andP e2) =>[
H7 H8];
move: (
norepik H8)=>
H5.
have H6: (
_x::
_x0) != [::];
first by done.
have H9: ([::
a,
_x &
_x0] != [::]);
first by done.
have H10: (
head false [::
a,
_x &
_x0] !=
false);
first by done.
move: (@
norepAddOrders i k [::
a,
_x &
_x0]
H8 H9 H10 H3)=>
H11.
rewrite /
behead in H11;
rewrite -
H11.
have H12: (
canAddOrders i (
k + 1) (
_x ::
_x0) [:: [::
i,
k & [::]]]);
last by rewrite H11;
apply: (
IHo H5 H12).
by apply: (
canAddOrders_tailnil H8 H10 H9 H3).
move:
H3;
rewrite /
canAddOrders -/
canAddOrders Bool.andb_comm e2.
case H4: (
_x0)=>[|
x1 x2].
case H5:((
_x !=
false) && (
i !=
k + 1)).
move: (
andP H5)=>[
H51 H52];
rewrite /=
H51 H52 /=.
have H6:(
i ==
k + 1)=
false;
first by apply/
eqP;
apply/
eqP.
by rewrite inE H6.
case H6: (
_x !=
false);
last by rewrite /=
H5.
rewrite H6 Bool.andb_true_l in H5;
rewrite H5 =>
H9.
have H7: (
canAddOrders i (
k + 1) (
_x ::
_x0) [::]);
last first.
have H8: (
k+1 == 0)=
false;
first by rewrite addn1.
rewrite H4 in IHo H7;
apply: (
IHo H2 H7).
by rewrite /=
H5 H4.
case H5: ((
i !=
k + 1) && (
_x !=
false));
last first.
rewrite -
H4 =>
H10.
have H8: ((
k + 1 == 0) =
false);
first by rewrite addn1.
have H9:(
canAddOrders i (
k + 1) (
_x ::
_x0) [::]);
first by rewrite /=
H4 H5 -
H4.
apply: (
IHo H2 H9).
have H8: (
k+1 == 0)=
false;
first by rewrite addn1.
move=>
H9;
rewrite -
H4.
have H10: (
canAddOrders i (
k + 1) (
_x ::
_x0) [::]);
first by rewrite /=
H4 H5.
apply: (
IHo H2 H10).
have H6: (
k + 1 == 0) =
false;
first by rewrite addn1.
have H7:(
norep ([:: [::
i;
k]] ++
addOrder_orders i k (
_x1 ::
_x2) ++
addOrder_concat
((
getfirstE k (
_x1 ::
_x2)), (
getlastE i (
_x1 ::
_x2)))));
last first.
have H8: (
canAddOrders i (
k + 1) (
_x ::
_x0)([:: [::
i;
k]] ++
addOrder_orders i k (
_x1 ::
_x2) ++
addOrder_concat
((
getfirstE k (
_x1 ::
_x2)), (
getlastE i (
_x1 ::
_x2)))));
last first.
apply:(
IHo H7 H8).
set x:= (
_x::
_x0).
move:
H3;
rewrite -/
x /=.
rewrite Bool.andb_comm in e2;
rewrite e2.
by case:(
canAddOrder i k (
_x1 ::
_x2) &&
canAOrder i k (
_x1 ::
_x2)).
rewrite norep_cat;
move: (
andP e2) => [
H10 H9].
rewrite (
norepik H9)
norep_cat.
have H11: (
canAddOrder i k (
_x1 ::
_x2) &&
canAOrder i k (
_x1 ::
_x2)).
move:
H3;
rewrite /
canAddOrders -/
canAddOrders H9 H10.
by case H12: (
canAddOrder i k (
_x1 ::
_x2) &&
canAOrder i k (
_x1 ::
_x2)).
move:(
andP H11)=> [
H111 H12].
move: (
canAddOrder_norep H9 H2 H111) => ->.
move: (
subseq_getfirstE k (
_x1 ::
_x2))(
subseq_getlastE i (
_x1 ::
_x2)) =>
HH1 HH2.
have H7:(
forall x :
seq nat,
x \
in ((
getfirstE k (
_x1 ::
_x2),
getlastE i (
_x1 ::
_x2)).1) ->
head 0
x =
k).
by rewrite /
fst =>
x H4;
apply: (
ingetfirst H4).
have H8:(
forall x :
seq nat,
x \
in ((
getfirstE k (
_x1 ::
_x2),
getlastE i (
_x1 ::
_x2)).2) ->
last 0
x =
i).
by rewrite /
snd =>
x H4;
apply: (
ingetlastE_last H4).
by move: (
norep_addOrder_concat H9 H2 H7 H8 HH1 HH2 H111 H12).
have H4: ((
_x1 ::
_x2)!=[::]);
first by done.
have H5: (
head false [::
a,
_x &
_x0] !=
false) && (
i!=
k)=
false;
first by done.
have H6: (
canAddOrders i (
k + 1) (
_x ::
_x0)(
_x1::
_x2));
last first.
have H7: (
k + 1 == 0) =
false;
first by rewrite addn1.
apply: (
IHo H2 H6).
rewrite Bool.andb_comm in e2.
have H6: ((
_x ::
_x0)!=[::]);
first by done.
by rewrite -(
canAddOrders_tail (
_x1 ::
_x2)
e2 H6).
Qed.
End canAddOrders.
Section proofAdm.
Lemma admis_aux ss (a:seqZ2) m2 m1:
norep (genDvfOrders (size ss * size a).+1 m2 m2 ss m1 [::] [::]).2.
Proof.
Lemma admis (ss: matZ2): norep (genOrders ss).
Proof.
elim H:
ss=> [|
a b HI];
first by done.
rewrite /
genOrders !
addn1 -
H.
have H2: (
a::
b =
a::
b);
first by done.
set m1:=
ss.
rewrite {-6}/
m1.
case HH:(
prop_cat (
genDvfOrders (
size ss *
size a).+1 0 0
ss m1 [::] [::]).2);
last by done.
by apply :
admis_aux.
Qed.
End proofAdm.
End rs_adm_prop5.
Section rs_adm_prop6.
Functional Scheme addOrder_orders_ind := Induction for addOrder_orders Sort Prop.
Lemma invf_inaddOrder_orders a i j ords: i!= j ->
a \in ords -> a \in addOrder_orders i j ords.
Proof.
functional induction (addOrder_orders i j ords); try by done.
move=> H; rewrite inE; move/orP=>[H1|H1]; first by rewrite (eqP H1) inE; by have -> //: (a0 == a0).
move: (IHl H H1) => H2.
by rewrite !mem_cat; apply/orP; right; apply/orP; right.
by rewrite e0.
Qed.
Lemma invf_inaddO a i j c ords:
a \in ords -> a \in addOrders i j c ords.
Proof.
functional induction (addOrders i j c ords); try by done.
+ move=> H; rewrite mem_cat; apply/orP; right.
rewrite /addOrder_orders -/addOrder_orders.
move:H; rewrite inE; move/orP =>[H2|H2]; first by rewrite (eqP H2) inE; by have -> //: (_x == _x).
move: (andP e2)=>[e21 e22].
rewrite mem_cat; apply/orP; right; rewrite e22 mem_cat; apply/orP; right.
apply:(invf_inaddOrder_orders e22 H2).
+ move=> H1; rewrite mem_cat; apply/orP; right; rewrite mem_cat; apply/orP; left.
move: (andP e2) =>[_ e22].
apply: (invf_inaddOrder_orders e22 H1).
+ move=> H1.
have H2: ( a \in [:: [:: i; k]] ++ addOrder_orders i k (_x1 :: _x2) ++
addOrder_concat (getfirstE k (_x1 :: _x2), getlastE i (_x1 :: _x2))); last apply: (IHo H2).
rewrite mem_cat; apply/orP; right; rewrite mem_cat; apply/orP; left; move: (andP e2) =>[_ e22].
apply: (invf_inaddOrder_orders e22 H1).
Qed.
Fixpoint schemaaddOrders (i k:nat)(s:seqZ2)(ords: orders)(im:nat):=
match s, ords with
|nil, _ => ords
|a::nil, nil => if (im == 0)
then if ((a!= false) && (i!=k))
then (i::k::nil)::nil
else nil
else nil
|a::nil, _ => let getf := (getfirstE k ords) in
let getl := (getlastE i ords) in
if (im == 0)
then if ((a!=false) && (i!=k))
then if ((getf == nil) || (getl == nil))
then ((i::k::nil)::nil ) ++ (addOrder_orders i k ords)
else ((i::k::nil)::nil ) ++(addOrder_orders i k ords)++(addOrder_concat (getf, getl))
else ords
else nil
|a::b, nil => if ((a != false) && (i != k))
then schemaaddOrders i (k+1) b ((i::k::nil)::nil)(im-1)
else schemaaddOrders i (k+1) b nil (im-1)
|a::b, _ => let getf := (getfirstE k ords) in
let getl := (getlastE i ords) in
if ((a != false) && (i != k))
then (schemaaddOrders i (k+1) b (((i::k::nil)::nil) ++ (addOrder_orders i k ords) ++ (addOrder_concat (getf, getl))) (im-1))
else schemaaddOrders i (k+1) b ords (im-1)
end.
Functional Scheme schemaaddOrders_ind := Induction for schemaaddOrders Sort Prop.
Lemma compij_in_addOrders (im k i:nat) l ords:
nth false l im!= false -> uniq (i::(im+ k)::nil) ->
(i :: (im + k) ::nil) \in addOrders i k l ords.
Proof.
functional induction (schemaaddOrders i k l ords im); first by rewrite nth_nil.
move: (eqP e2)=> -> H2 H3.
by rewrite /= e3 add0n inE.
rewrite (eqP e2)=> H2; rewrite /addOrders e3 add0n.
move: H2; rewrite /= inE Bool.andb_true_r => H3 H4.
by move: e3; rewrite H3 H4.
case H2: im=>[|im1]; first by move:e2; rewrite H2.
by move:e2; rewrite H2 /= => _; move/eqP; rewrite nth_nil.
rewrite /addOrders e3 e4 (eqP e2)=> H2 H3.
by rewrite add0n /= inE; apply/orP; left.
rewrite /addOrders e3 e4 (eqP e2)=> H2 H3.
by rewrite add0n /= inE; apply/orP; left.
rewrite (eqP e2)=> H2; rewrite /addOrders e3 add0n.
move: H2; rewrite /= inE => H3.
by move: e3; rewrite H3 Bool.andb_true_l => ->.
case H2: im=>[|im1]; first by move:e2; rewrite H2.
by move:e2; rewrite H2 /= => _; move/eqP; rewrite nth_nil.
set x:= (_x :: _x0).
case H1: (im) =>[|n1].
rewrite add0n /nth=> H4 H5.
rewrite /= -/addOrders e2 /x.
have H7: ([:: i; k] \in [:: [:: i; k]]); first by rewrite inE.
apply: (@invf_inaddO [:: i; k] i (k+1) (_x::_x0)[:: [:: i; k]] H7).
move: (ltn0Sn k); rewrite -(addn1 k) => H2 H4 H5.
have H3: (0 < im); first by rewrite H1.
rewrite -H1.
have H8:nth false (_x :: _x0) (im - 1) != false.
by move: H4; rewrite subn1 /x H1 /=.
have H9: (im - 1 + (k + 1)) = im + k.
by rewrite H1 addn1 -H1 !subn1 H1 /= addnS addSn.
rewrite -H1 -H9 in H5; rewrite -H9 /= -/addOrders e2 /x.
apply: (IHo H8 H5).
set x:= (_x :: _x0).
rewrite /addOrders -/addOrders e2 /x.
case H1: (im) =>[|n1].
rewrite add0n /nth.
move=> H5; move:e2; rewrite H5 Bool.andb_true_l; move/eqP => ->.
by rewrite /uniq /= inE Bool.andb_true_r; move/eqP.
move: (ltn0Sn k); rewrite -(addn1 k) => H2 H4 H5.
have H3: (0 < im); first by rewrite H1.
have H8: nth false (_x :: _x0) (im - 1) != false; first by move: H4; rewrite H1 subn1.
have H9: (im - 1 + (k + 1)) = im + k.
by rewrite H1 addn1 -H1 !subn1 H1 /= addnS addSn.
move:H5; rewrite -H1 -H9; apply: (IHo H8).
set x:= (_x :: _x0).
case H1: (im) =>[|n1].
rewrite add0n /nth.
move=> H5 H6.
rewrite /addOrders -/addOrders e2 /x.
have H7: ([:: i; k] \in ([:: [:: i; k]] ++ addOrder_orders i k (_x1 :: _x2) ++
addOrder_concat (getfirstE k (_x1 :: _x2), getlastE i (_x1 :: _x2)))); first
by rewrite mem_cat inE; apply/orP; left.
apply: (@invf_inaddO [:: i; k] i (k+1) (_x::_x0)([:: [:: i; k]] ++
addOrder_orders i k (_x1 :: _x2) ++
addOrder_concat (getfirstE k (_x1 :: _x2), getlastE i (_x1 :: _x2))) H7).
move: (ltn0Sn k); rewrite -(addn1 k) => H5 H6 H7.
have H3: (0 < im); first by rewrite H1.
have H8: nth false (_x :: _x0) (im - 1) != false; first by move: H6; rewrite H1 subn1.
have H9: (im - 1 + (k + 1)) = im + k.
by rewrite H1 addn1 -H1 !subn1 H1 /= addnS addSn.
rewrite /= -/addOrders e2 /x.
move:H7; rewrite -H1 -H9 => H7; apply: (IHo H8 H7).
set x:= (_x :: _x0).
rewrite /addOrders -/addOrders e2 /x.
case H1: (im) =>[|n1].
rewrite add0n /nth.
move=> H5; move:e2; rewrite H5 Bool.andb_true_l; move/eqP => ->.
by rewrite /uniq /= inE Bool.andb_true_r; move/eqP.
move: (ltn0Sn k); rewrite -(addn1 k) => H2 H4 H5.
have H3: (0 < im); first by rewrite H1.
have H8: nth false (_x :: _x0) (im - 1) != false; first by move: H4; rewrite H1 subn1.
have H9: (im - 1 + (k + 1)) = im + k.
by rewrite H1 addn1 -H1 !subn1 H1 /= addnS addSn.
move:H5; rewrite -H1 -H9; apply: (IHo H8).
Qed.
Lemma compijsub (k1 k2:nat)(a:seqZ2)(s: matZ2):
k1 > 0 -> compij k1 k2 (a::s) = compij k1.-1 k2 s.
Proof.
move=> H; rewrite /compij.
have ->: ((nth [::] (a :: s) (k1)) =(nth [::] s (k1.-1))); last by done.
case H1: k1=>[|k]; first by move:H; rewrite H1.
by rewrite /=.
Qed.
Fixpoint schemagetcol1 (c:nat)(s: matZ2)(i:nat):seqZ2 :=
match s with
|nil => nil
|a::b => (schemagetcol1 c b (i -1))
end.
Functional Scheme schemagetcol1_ind := Induction for schemagetcol1 Sort Prop.
Lemma compij_nth im jk M:
compij im jk M = nth false (getcol jk M) im.
Proof.
functional induction (schemagetcol1 jk M im); first by rewrite /compij !nth_nil.
case H1: i => [|i1]; first by rewrite /compij.
have H3: 0 < i; first by rewrite H1.
by rewrite -H1 (compijsub jk _x b H3) -subn1 IHs /getcol -/getcol cat1s H1 !subn1.
Qed.
Lemma pairs (i j i0 j0:nat): (i,j)== (i0,j0) -> (i==i0)/\ (j ==j0).
Proof.
by move=> H; rewrite (pair_eq1 H) (pair_eq2 H).
Qed.
Lemma indif0_order ik jk im p i j M M1 ords vf :
((ik, jk) \in vf -> compij im jk M != false -> (ik::im::nil) \in ords) ->
ik!= im -> (ik,jk)\in (genDvfOrders p i j M M1 vf ords).1 ->
compij im jk M != false -> (ik::im::nil) \in (genDvfOrders p i j M M1 vf ords).2.
Proof.
functional induction (genDvfOrders p i j M M1 vf ords); try by done; try by apply:IHp0.
+ rewrite /= => H1 HH.
rewrite (mem_cat (ik, jk) vf [:: (i, firstElem1 j a)]).
move/orP=>[H2| H3] H4; first by move: (H1 H2 H4).
move: H3; rewrite inE => H5; move: (pairs H5) =>[H6 H7]; rewrite (eqP H6) -(eqP H7).
rewrite compij_nth in H4.
have H8:(0 < 1); first by done.
have H9:(uniq [::i;im]); first by move:(eqP H6) HH => -> /=; rewrite inE => ->.
move: (@compij_in_addOrders im 0 i (getcol jk mm)[::]); rewrite addn0=> H10.
by apply: (H10 H4 H9).
+ rewrite /= => H1 HH.
rewrite (mem_cat (ik, jk) vf [:: (i, firstElem1 j a)]).
move/orP=>[H2| H3] H4; first by move: (H1 H2 H4); apply:(invf_inaddO i 0 ((getcol (firstElem1 j a) mm))).
move: H3; rewrite inE => H5; move: (pairs H5) =>[H6 H7]; rewrite (eqP H6) -(eqP H7).
rewrite compij_nth in H4.
have H8:(0 < 1); first by done.
have H9:(uniq [::i;im]); first by move:(eqP H6) HH => -> /=; rewrite inE => ->.
move: (@compij_in_addOrders im 0 i (getcol jk mm)(e3::f)); rewrite addn0=> H10.
by apply: (H10 H4 H9).
+ move=> H1 H2 H3.
have H4: (((ik, jk) \in addcvd i (firstElem1 j a) vf -> compij im jk mm != false ->
[:: ik; im] \in addOrders i 0 (getcol (firstElem1 j a) mm) [::])); last by apply: (IHp0 H4 H2 H3).
rewrite /addcvd mem_cat; move/orP=>[H4|H4] hh; last by move: (H1 H4 hh).
move:H4; rewrite inE => H5.
move: (pairs H5)=>[H61 H62]; move:(eqP H61)(eqP H62)=> -> <-.
rewrite compij_nth in hh.
have H8:(0 < 1); first by done.
have H9:(uniq [::i;im]); first by move:(eqP H61) H2 => -> /=; rewrite inE /= => ->.
move: (@compij_in_addOrders im 0 i (getcol jk mm)[::]); rewrite addn0=> H10.
by apply: (H10 hh H9).
+ move=> H1 H2 H3.
have H4: (((ik, jk) \in addcvd i (firstElem1 j a) vf -> compij im jk mm != false ->
[:: ik; im] \in addOrders i 0 (getcol (firstElem1 j a) mm) (e3::f))); last by apply: (IHp0 H4 H2 H3).
rewrite /addcvd mem_cat; move/orP=>[H4|H4] hh; last first.
move: (H1 H4 hh)=> H5; by rewrite (invf_inaddO i 0 ((getcol (firstElem1 j a) mm)) H5).
move:H4; rewrite inE => H5.
move: (pairs H5)=>[H61 H62]; move:(eqP H61)(eqP H62)=> -> <-.
rewrite compij_nth in hh.
have H8:(0 < 1); first by done.
have H9:(uniq [::i;im]); first by move:(eqP H61) H2 => -> /=; rewrite inE /= => ->.
move: (@compij_in_addOrders im 0 i (getcol jk mm)(e3::f)); rewrite addn0=> H10.
by apply: (H10 hh H9).
Qed.
Lemma indif0_order1 M : forall ik jk im,
(ik,jk)\in (dvford M) -> ik!= im ->
compij im jk M != false -> (ik::im::nil) \in genOrders M.
Proof.
move=> ik jk im H; move:(indvford_genDvf H).
rewrite /genDvf /genOrders.
case H1: M => [|a b]; first by done.
case HH: (prop_cat (genDvfOrders (size (a :: b) * size a + 1) 0 0 (a :: b) (a :: b) [::] [::]).2); last by rewrite in_nil.
move: HH => _.
rewrite -H1 => H4 H6 H7.
have H3:((ik, jk) \in [::] -> compij im jk M != false -> (ik::im::nil) \in [::]); first by done.
apply: (indif0_order H3 H6 H4 H7).
Qed.
End rs_adm_prop6.
End admissible.
Section rs_adm_prop7.
Lemma propcat_in_in_cat M: prop_cat (genOrders M).
Proof.
elim H: M => [|a b HI]; first by done.
rewrite /genOrders !addn1 -H.
by case HH: (prop_cat (genDvfOrders (size M * size a).+1 0 0 M M [::] [::]).2).
Qed.
Lemma in_in_cat (M:matZ2):
let ords:= (genOrders M) in
(forall a b s p, (a::s) \in ords -> (last 0 s = b) -> (b::p) \in ords -> ((a::s)++p) \in ords).
Proof.
apply:(prop_cat_prop_cat2 ( propcat_in_in_cat M)).
Qed.
End rs_adm_prop7.
Section dvfordgenOrder_is_Vecfieldadmord.
Variable M: matZ2.
Variable m n: nat.
Hypotheses ismatrix: is_matrix m n M.
Lemma dvfordisVecfieldadm:
Vecfieldadm M (dvford M)(genOrders M).
Proof.
case H1: M=>[|s1 s2]; first by done.
have HH: (M!=[::]); first by rewrite H1.
rewrite -H1 /Vecfieldadm.
rewrite (propSizef_ord M) (@propSizes_ord m n M HH ismatrix)
(norepfst_ord M)(norepsnd_ord M)(admis M).
split; split; split; split; split.
apply: v_in_genDvf_Mv1_ord.
split; first by done.
split; first by apply: ordered_dvfg.
split; first by apply : indif0_order1.
apply: in_in_cat.
Qed.
End dvfordgenOrder_is_Vecfieldadmord.