Require Import SetoidList.
Require Import Coqlib.
Require Import Maps.
Require Import Iteration.
Require Import SSAfastliveutils.
Require Import SSAfastliveprecomputeRT.
Local Open Scope positive_scope.
Module Import Definitions.
Inductive reachable (
g:
graph) (
root:
positive) :
positive ->
Prop :=
|
reachable_root:
reachable g root root
|
reachable_succ:
forall x succs y,
reachable g root x ->
g!
x =
Some succs ->
In y succs ->
reachable g root y.
Lemma reachable_trans :
forall g u1 u2 u3,
reachable g u1 u2 ->
reachable g u2 u3 ->
reachable g u1 u3.
Proof.
intros. revert dependent u1. induction H0; intros.
- assumption.
- econstructor. apply IHreachable; eassumption. eassumption. eassumption.
Qed.
Inductive reduced_reachable (
g:
graph) (
back :
list (
positive *
positive))
(
root:
positive) :
positive ->
Prop :=
|
reduced_reachable_root:
reduced_reachable g back root root
|
reduced_reachable_succ:
forall x succs y,
reduced_reachable g back root x ->
g!
x =
Some succs ->
In y succs ->
~
In (
x,
y)
back ->
reduced_reachable g back root y.
Lemma reduced_reachable_trans :
forall g back u1 u2 u3,
reduced_reachable g back u1 u2 ->
reduced_reachable g back u2 u3 ->
reduced_reachable g back u1 u3.
Proof.
intros. revert dependent u1. induction H0; intros.
- assumption.
- econstructor. apply IHreduced_reachable; eassumption.
eassumption. eassumption. eassumption.
Qed.
Lemma reduced_reachable_pred :
forall g back u v,
reduced_reachable g back u v <->
u =
v \/
exists succs w,
g !
u =
Some succs /\
In w succs /\ ~
In (
u,
w)
back /\
reduced_reachable g back w v.
Proof.
split;
intros.
{
induction H.
-
left;
reflexivity.
-
right.
destruct IHreduced_reachable.
+
subst x.
exists succs,
y.
split.
assumption.
split.
assumption.
split.
assumption.
constructor.
+
destruct H3 as (
succs1 &
w1 &
H31 &
H32 &
H33 &
H34).
exists succs1,
w1.
split; [|
split; [|
split]];
try assumption.
eapply reduced_reachable_succ;
eassumption.
}
{
destruct H.
subst v.
constructor.
destruct H as (
succs &
w &
H1 &
H2 &
H3 &
H4).
revert dependent u.
induction H4;
intros.
-
eapply reduced_reachable_succ; [
constructor|
eassumption..].
-
eapply reduced_reachable_succ.
apply IHreduced_reachable.
assumption.
assumption.
eassumption.
eassumption.
eassumption.
}
Qed.
Lemma reduced_reachable_is_reachable :
forall g back u v,
reduced_reachable g back u v ->
reachable g u v.
Proof.
induction 1; econstructor; eauto.
Qed.
Inductive reduced_reachable_bis (
g:
graph) (
back :
list (
node *
node))
:
positive ->
positive ->
Prop :=
|
reduced_reachable_bis_root:
forall root,
reduced_reachable_bis g back root root
|
reduced_reachable_bis_pred:
forall root succs x y,
g !
root =
Some succs ->
In x succs -> ~
In (
root,
x)
back ->
reduced_reachable_bis g back x y ->
reduced_reachable_bis g back root y.
Lemma reduced_reachable_bis_succ :
forall g back u v,
reduced_reachable_bis g back u v <->
u =
v \/
exists w succs,
reduced_reachable_bis g back u w /\
g!
w =
Some succs /\
In v succs /\
~
In (
w,
v)
back.
Proof.
split; intros.
- induction H.
+ left; reflexivity.
+ right. destruct IHreduced_reachable_bis.
* subst y. exists root, succs. repeat split; try eassumption.
constructor.
* destruct H3 as (w & succs' & H31 & H32 & H33 & H34).
exists w, succs'. repeat split; try eassumption.
econstructor; eauto.
- destruct H.
+ subst v. constructor.
+ destruct H as (w & succs & H1 & H2 & H3 & H4).
induction H1.
* econstructor; [eassumption..|constructor].
* econstructor; eauto.
Qed.
Lemma reduced_reachable_equiv :
forall g back u v,
reduced_reachable g back u v <->
reduced_reachable_bis g back u v.
Proof.
Definition is_in_t_up g back u v :=
~
reduced_reachable g back u v
/\
exists s,
In (
s,
v)
back
/\
reduced_reachable g back u s.
Definition directly_included r u v :=
exists n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) /\
r !
v =
Some (
m1,
m2) /\
is_included (
m1,
m2) (
n1,
n2).
Lemma directly_included_refl :
forall r u,
r !
u <>
None ->
directly_included r u u.
Proof.
intros. destruct (r !u) as [(n1, n2)|] eqn:Heq; [|contradiction].
exists n1, n2, n1, n2.
split; [|split]; try assumption.
split; reflexivity.
Qed.
Lemma directly_included_trans :
forall r u v w,
directly_included r u v ->
directly_included r v w ->
directly_included r u w.
Proof.
intros.
destruct H as (
n1 &
n2 &
m1 &
m2 &
H1 &
H2 &
H3).
destruct H0 as (
m1' &
m2' &
o1 &
o2 &
H01 &
H02 &
H03).
exists n1,
n2,
o1,
o2.
rewrite H2 in H01.
inv H01.
split; [|
split];
eauto using is_included_trans.
Qed.
Lemma directly_included_dec :
forall r u v,
directly_included r u v \/ ~
directly_included r u v.
Proof.
intros r u v.
unfold directly_included.
destruct (
r !
u)
as [(
n1,
n2)|].
-
destruct (
r !
v)
as [(
m1,
m2)|].
+
destruct (
is_included_dec m1 m2 n1 n2).
*
left.
exists n1,
n2,
m1,
m2.
eauto.
*
right.
intros (
n1' &
n2' &
m1' &
m2' &
contra1 &
contra2 &
contra3).
congruence.
+
right.
intros (
_ &
_ &
m1' &
m2' &
_ &
contra2 &
_).
discriminate.
-
right.
intros (
n1' &
n2' &
_ &
_ &
contra1 &
_).
discriminate.
Qed.
Definition cross_included r c u v :=
exists set w,
c !
u =
Some set /\
set !
w =
Some tt /\
directly_included r w v.
Lemma can_reach_spec :
forall r c u v
(
r_defined :
r !
u <>
None),
can_reach r c u v =
true <->
cross_included r c u v.
Proof.
intros.
unfold can_reach,
cross_included.
destruct (
r !
v)
as [(
m1,
m2)|]
eqn:
Hv.
-
split;
intros.
+
destruct (
c !
u)
as [
set|]
eqn:
Hset; [|
discriminate].
exists set.
revert H.
apply PTree_Properties.fold_rec.
*
intros.
apply H0 in H1.
destruct H1 as (
w &
H1).
exists w.
rewrite <- !
H.
split; [
reflexivity |
apply H1].
*
intros;
discriminate.
*
intros.
apply orb_true_iff in H2.
destruct H2.
apply H1 in H2.
destruct H2 as (
w &
H2).
exists w.
repeat split;
try apply H2.
rewrite PTree.gso.
apply H2.
destruct H2 as (
_ &
H2 &
_).
congruence.
exists k.
split; [
reflexivity|].
destruct (
r !
k)
as [(
o1,
o2)|]
eqn:
Heq; [|
discriminate].
split.
rewrite PTree.gss.
destruct v0;
reflexivity.
exists o1,
o2,
m1,
m2.
apply test_is_included_spec in H2.
split; [|
split];
assumption.
+
destruct H as (
set &
w &
H1 &
H2 &
H3).
rewrite H1.
revert H2.
apply PTree_Properties.fold_rec.
*
intros.
apply H0.
rewrite H;
assumption.
*
intros H.
rewrite PTree.gempty in H.
discriminate.
*
intros.
rewrite PTree.gsspec in H4.
apply orb_true_iff.
destruct (
peq w k).
--
subst k.
right.
destruct H3 as (
o1 &
o2 &
m1' &
m2' &
H31 &
H32 &
H33).
rewrite H31.
apply test_is_included_spec.
congruence.
--
left;
auto.
-
split;
intros; [
discriminate|].
destruct H as (
_ &
_ &
_ &
_ &
_ &
_ &
m1 &
m2 &
_ &
H &
_).
congruence.
Qed.
End Definitions.
Section POSTORDER.
Variable ginit:
graph.
Variable root:
node.
Inductive invariant (
s:
state) :
Prop :=
Invariant
(
SUB:
forall x y,
s.(
gr)!
x =
Some y ->
ginit!
x =
Some y)
(
ROOT:
s.(
gr)!
root =
None)
(
BELOW1 :
forall x n l post,
In (
x,
n,
l,
post)
s.(
wrk) ->
Plt n s.(
next))
(
BELOW2:
forall u n1 n2,
s.(
r)!
u =
Some (
n1,
n2) ->
Ple n1 n2 /\
Plt n2 s.(
next))
(
BELOW3 :
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
forall v m,
s.(
r) !
v <>
Some (
n,
m))
(
BELOW4 :
NoDupA (
fun '(
_,
n1,
_,
_) '(
_,
n2,
_,
_) =>
n1 =
n2)
s.(
wrk))
(
INJ:
forall u v m n1 n2,
s.(
r)!
u =
Some (
m,
n1) ->
s.(
r)!
v =
Some (
m,
n2) ->
u =
v)
(
REM:
forall u l,
s.(
gr)!
u =
Some l ->
s.(
r)!
u =
None)
(
COLOR:
forall u succs n1 n2 v,
ginit!
u =
Some succs ->
s.(
r)!
u =
Some (
n1,
n2) ->
In v succs ->
s.(
gr)!
v =
None)
(
WKLIST:
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
s.(
gr)!
u =
None /\
exists l',
ginit!
u =
Some l'
/\ (
forall v,
In v l' -> ~
In v l ->
s.(
gr)!
v =
None)
/\
incl l l')
(
GREY:
forall u,
ginit!
u <>
None ->
s.(
gr)!
u =
None ->
s.(
r)!
u =
None ->
exists n l post,
In (
u,
n,
l,
post)
s.(
wrk)).
Inductive postcondition
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition
(
INJ:
let '(
r,
c,
t,
back) :=
acc in forall u v m n1 n2,
r!
u =
Some (
m,
n1) ->
r!
v =
Some (
m,
n2) ->
u =
v)
(
ROOT:
let '(
r,
c,
t,
back) :=
acc in ginit!
root <>
None ->
r!
root <>
None)
(
SUCCS:
let '(
r,
c,
t,
back) :=
acc in
forall x succs y,
ginit!
x =
Some succs ->
r!
x <>
None ->
In y succs ->
ginit!
y <>
None ->
r!
y <>
None)
(
BELOW :
let '(
r,
c,
t,
back) :=
acc in
forall u n1 n2,
r !
u =
Some (
n1,
n2) ->
Ple n1 n2).
Lemma transition_spec:
forall dom_pre s,
invariant s ->
match transition dom_pre s with inr s' =>
invariant s' |
inl m =>
postcondition m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l].
-
constructor;
intros.
+
eauto.
+
caseEq ((
r s)!
root);
intros.
congruence.
exploit GREY;
eauto.
intros (?, (?,(?,?)));
contradiction.
+
destruct (
s.(
r)!
x)
as [(
n1,
n2)|]
eqn:?;
try congruence.
destruct (
s.(
r)!
y)
eqn:?;
try congruence.
exploit COLOR;
eauto.
intros.
exploit GREY;
eauto.
intros (?, (?,(?,?)));
contradiction.
+
eapply BELOW2.
eassumption.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
eauto.
*
assumption.
*
eapply BELOW1.
right.
eassumption.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
inv H.
exploit BELOW1.
left;
reflexivity.
xomega.
--
eauto.
*
rewrite PTree.gsspec.
destruct (
peq v u).
--
inv BELOW4.
intros contra.
apply H2.
apply InA_alt.
eexists.
split; [|
apply H].
congruence.
--
eapply BELOW3.
right;
eassumption.
*
inv BELOW4.
assumption.
*
rewrite PTree.gsspec in H.
rewrite PTree.gsspec in H0.
destruct (
peq u0 u), (
peq v u);
subst.
--
reflexivity.
--
eapply BELOW3 in H0.
contradiction.
inv H.
left.
reflexivity.
--
eapply BELOW3 in H.
contradiction.
inv H0.
left.
reflexivity.
--
eauto.
*
rewrite PTree.gso;
eauto.
red;
intros;
subst u0.
exploit (
WKLIST u);
eauto with coqlib.
intros [
A _].
congruence.
*
rewrite PTree.gsspec in H0.
destruct (
peq u0 u).
inv H0.
exploit (
WKLIST u);
eauto with coqlib.
intros [
A [
l' [
B C]]].
assert (
l' =
succs)
by congruence.
subst l'.
apply C;
auto.
eauto.
*
eapply WKLIST.
eauto with coqlib.
*
rewrite PTree.gsspec in H1.
destruct (
peq u0 u).
inv H1.
exploit GREY;
eauto.
intros [
n' [
l' [
post A]]].
simpl in A;
destruct A.
congruence.
exists n',
l',
post;
auto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
rewrite PTree.grspec in H.
destruct (
PTree.elt_eq x v);
eauto.
inv H.
--
rewrite PTree.gro.
auto.
congruence.
--
destruct H as [
H | [
H |
H]].
++
inv H.
xomega.
++
inv H.
apply Plt_trans_succ.
eapply BELOW1.
left;
reflexivity.
++
apply Plt_trans_succ.
eapply BELOW1.
right;
eassumption.
--
apply BELOW2 in H.
destruct H.
split;
eauto using Plt_trans_succ.
--
destruct H as [
H | [
H |
H]].
++
inv H.
intros contra.
apply BELOW2 in contra.
xomega.
++
inv H.
eapply BELOW3.
left;
reflexivity.
++
eapply BELOW3.
right;
eassumption.
--
constructor;
eauto.
intros contra.
apply InA_alt in contra.
destruct contra as [(((
u0,
n0),
l0),
post0) [
contra1 contra2]].
exploit BELOW1.
eassumption.
subst n0.
xomega.
--
eauto.
--
rewrite PTree.grspec in H.
destruct (
PTree.elt_eq u0 v);
eauto.
inv H.
--
rewrite PTree.grspec.
destruct (
PTree.elt_eq v0 v);
eauto.
--
destruct H as [
H | [
H |
H]].
++
inv H.
split.
apply PTree.grs.
exists l0;
split.
eauto.
split.
intros.
contradiction.
apply incl_refl.
++
inv H.
exploit WKLIST;
eauto with coqlib.
intros [
A [
l' [
B [
C D]]]].
split.
**
rewrite PTree.grspec.
destruct (
PTree.elt_eq u0 v);
auto.
**
exists l';
split.
auto.
split.
intros.
rewrite PTree.grspec.
destruct (
PTree.elt_eq v0 v);
auto.
assumption.
++
exploit (
WKLIST u0);
eauto with coqlib.
intros [
A [
l' [
B [
C D]]]].
split.
**
rewrite PTree.grspec.
destruct (
PTree.elt_eq u0 v);
auto.
**
exists l';
split;
auto.
split.
intros.
rewrite PTree.grspec.
destruct (
PTree.elt_eq v0 v);
auto.
assumption.
--
rewrite PTree.grspec in H0.
destruct (
PTree.elt_eq u0 v)
in H0.
subst.
eauto with coqlib.
exploit GREY;
eauto.
simpl.
intros [
n1 [
l1 [
post1 A]]].
destruct A.
++
inv H2.
eexists;
eauto.
++
do 3
eexists;
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros;
eauto.
**
destruct H.
---
inv H.
eapply BELOW1.
left.
reflexivity.
---
eapply BELOW1.
right.
eassumption.
**
destruct H.
---
inv H.
eapply BELOW3.
left;
reflexivity.
---
eapply BELOW3.
right.
eassumption.
**
inv BELOW4.
constructor.
---
intros contra.
apply H1.
apply InA_alt in contra.
apply InA_alt.
destruct contra as [(((
u0,
n0),
l01),
post1) [
contra1 contra2]].
exists (
u0,
n0,
l01,
post1).
split;
assumption.
---
assumption.
**
destruct H.
---
inv H.
exploit WKLIST;
eauto with coqlib.
intros [
A [
l' [
B [
C D]]]].
split.
auto.
exists l';
split.
auto.
split.
intros.
destruct (
peq v v0).
congruence.
apply C;
auto.
simpl.
intuition congruence.
eapply incl_cons_inv;
eassumption.
---
eapply WKLIST;
eauto with coqlib.
**
exploit GREY;
eauto.
intros [
n3 [
l3 [
post3 A]]].
simpl in A.
destruct A.
inv H2.
do 3
eexists;
eauto.
do 3
eexists;
eauto.
++
constructor;
simpl;
intros;
eauto.
**
destruct H.
---
inv H.
eapply BELOW1.
left.
reflexivity.
---
eapply BELOW1.
right.
eassumption.
**
destruct H.
---
inv H.
eapply BELOW3.
left;
reflexivity.
---
eapply BELOW3.
right.
eassumption.
**
inv BELOW4.
constructor.
---
intros contra.
apply H1.
apply InA_alt in contra.
apply InA_alt.
destruct contra as [(((?, ?), ?), ?) [
contra1 contra2]].
eexists (
_,
_,
_,
_).
split;
eassumption.
---
assumption.
**
destruct H.
---
inv H.
exploit WKLIST;
eauto with coqlib.
intros [
A [
l' [
B [
C D]]]].
split.
auto.
exists l';
split.
auto.
split.
intros.
destruct (
peq v v0).
congruence.
apply C;
auto.
simpl.
intuition congruence.
eapply incl_cons_inv;
eassumption.
---
eapply WKLIST;
eauto with coqlib.
**
exploit GREY;
eauto.
intros [
n3 [
l3 [
post3 A]]].
simpl in A.
destruct A.
inv H2.
do 3
eexists;
eauto.
do 3
eexists;
eauto.
-- {
constructor;
simpl;
intros;
eauto.
**
destruct H.
---
inv H.
eapply BELOW1.
left.
reflexivity.
---
eapply BELOW1.
right.
eassumption.
**
destruct H.
---
inv H.
eapply BELOW3.
left;
reflexivity.
---
eapply BELOW3.
right.
eassumption.
**
inv BELOW4.
constructor.
---
intros contra.
apply H1.
apply InA_alt in contra.
apply InA_alt.
destruct contra as [(((?, ?), ?), ?) [
contra1 contra2]].
eexists (
_,
_,
_,
_).
split;
eassumption.
---
assumption.
**
destruct H.
---
inv H.
exploit WKLIST;
eauto with coqlib.
intros [
A [
l' [
B [
C D]]]].
split.
auto.
exists l';
split.
auto.
split.
intros.
destruct (
peq v v0).
congruence.
apply C;
auto.
simpl.
intuition congruence.
eapply incl_cons_inv;
eassumption.
---
eapply WKLIST;
eauto with coqlib.
**
exploit GREY;
eauto.
intros [
n3 [
l3 [
post3 A]]].
simpl in A.
destruct A.
inv H2.
do 3
eexists;
eauto.
do 3
eexists;
eauto. }
Qed.
Lemma initial_state_spec:
invariant (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
root has succs *)
constructor;
simpl;
intros.
sub *)
rewrite PTree.grspec in H.
destruct (
PTree.elt_eq x root).
inv H.
auto.
root *)
apply PTree.grs.
below *)
destruct H; [|
contradiction].
inv H.
xomega.
below 2 *)
rewrite PTree.gempty in H;
inv H.
below 3 *)
rewrite PTree.gempty.
discriminate.
below 4 *)
constructor.
intros contra;
inversion contra.
constructor.
inj *)
rewrite PTree.gempty in H;
inv H.
rem *)
apply PTree.gempty.
color *)
rewrite PTree.gempty in H0;
inv H0.
wklist *)
destruct H;
inv H.
split.
apply PTree.grs.
eexists;
split;
eauto.
split;
intuition.
grey *)
rewrite PTree.grspec in H0.
destruct (
PTree.elt_eq u root).
subst.
eexists;
eauto.
contradiction.
root has no succs *)
constructor;
simpl;
intros.
sub *)
auto.
root *)
auto.
below1 *)
contradiction.
below 2 *)
rewrite PTree.gempty in H;
inv H.
below 3 *)
rewrite PTree.gempty;
discriminate.
below 4 *)
constructor.
inj *)
rewrite PTree.gempty in H;
inv H.
rem *)
apply PTree.gempty.
color *)
rewrite PTree.gempty in H0;
inv H0.
wklist *)
contradiction.
grey *)
contradiction.
Qed.
Inductive black_reduced_reachable_bis (
g:
graph)
(
r:
PTree.t (
positive *
positive)) (
back :
list (
node *
node))
:
node ->
node ->
Prop :=
|
black_reduced_reachable_bis_root:
forall root,
black_reduced_reachable_bis g r back root root
|
black_reduced_reachable_bis_pred:
forall root succs x y,
g !
root =
Some succs ->
In x succs ->
r !
x <>
None -> ~
In (
root,
x)
back ->
black_reduced_reachable_bis g r back x y ->
black_reduced_reachable_bis g r back root y.
Lemma black_reduced_reachable_bis_succ :
forall g r back u v,
black_reduced_reachable_bis g r back u v <->
u =
v \/
exists w succs,
black_reduced_reachable_bis g r back u w /\
g!
w =
Some succs /\
In v succs /\
r !
v <>
None /\ ~
In (
w,
v)
back.
Proof.
split; intros.
- induction H.
+ left; reflexivity.
+ right. destruct IHblack_reduced_reachable_bis.
* subst y. exists root0, succs. repeat split; try eassumption.
constructor.
* destruct H4 as (w & succs' & H31 & H32 & H33 & H34 & H35).
exists w, succs'. repeat split; try eassumption.
econstructor; eauto.
- destruct H.
+ subst v. constructor.
+ destruct H as (w & succs & H1 & H2 & H3 & H4 & H5).
induction H1.
* econstructor; [eassumption..|constructor].
* econstructor; eauto.
Qed.
Lemma black_reduced_reachable_bis_is_reduced_reachable :
forall g r back u v,
black_reduced_reachable_bis g r back u v ->
reduced_reachable g back u v.
Proof.
Lemma black_reduced_reachable_bis_monotone :
forall g r back u v w n1 n2,
black_reduced_reachable_bis g r back u v ->
black_reduced_reachable_bis g (
PTree.set w (
n1,
n2)
r)
back u v.
Proof.
intros.
induction H;
econstructor;
eauto.
rewrite PTree.gsspec.
destruct (
peq x w); [
discriminate|
assumption].
Qed.
Lemma black_reduced_reachable_bis_back :
forall g r back u v x y,
black_reduced_reachable_bis g r back u v ->
r !
y =
None ->
black_reduced_reachable_bis g r ((
x,
y) ::
back)
u v.
Proof.
intros. induction H.
- constructor.
- econstructor; eauto.
intros contra. destruct contra; [|contradiction].
congruence.
Qed.
Inductive invariant4 (
s:
state) :
Prop :=
Invariant4
(
WRK_NO_DUP :
NoDupA (
fun '(
u,
_,
_,
_) '(
v,
_,
_,
_) =>
u =
v)
s.(
wrk))
(
WRK_NOT_BLACK :
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
s.(
r) !
u =
None)
(
WRK_DONE :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v,
In v l' -> ~
In v l ->
s.(
r) !
v <>
None \/
In (
u,
v)
s.(
back)))
(
CLASSIFY_BLACK :
forall u succs v,
ginit !
u =
Some succs ->
s.(
r)!
u <>
None ->
In v succs ->
In (
u,
v)
s.(
back)
\/ (
exists set,
s.(
c) !
u =
Some set /\
set !
v =
Some tt)
\/
directly_included s.(
r)
u v)
(
CLASSIFY_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v,
In v l' -> ~
In v l ->
In (
u,
v)
s.(
back)
\/ (
s_c !
v =
Some tt)
\/
exists n1 n2,
s.(
r) !
v =
Some (
n1,
n2) /\
n <=
n1))
(
CROSS_TARGETS_BLACK_GRAY :
forall u n l s_c s_t w,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
s_c !
w =
Some tt ->
s.(
r) !
w <>
None)
(
CROSS_TARGETS_BLACK_BLACK :
forall u set v,
s.(
c) !
u =
Some set ->
set !
v =
Some tt ->
s.(
r) !
v <>
None)
(
CROSS_UPWARDS_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v set w,
In v l' -> ~
In v l -> ~
In (
u,
v)
s.(
back) ->
s.(
c) !
v =
Some set ->
set !
w =
Some tt ->
s_c !
w =
Some tt))
(
CROSS_UPWARDS_BLACK :
forall u succs v set w,
ginit !
u =
Some succs ->
s.(
r) !
u <>
None ->
In v succs -> ~
In (
u,
v)
s.(
back) ->
s.(
c) !
v =
Some set ->
set !
w =
Some tt ->
~
directly_included s.(
r)
u w ->
exists set',
s.(
c) !
u =
Some set' /\
set' !
w =
Some tt)
(
CROSS_REFL :
forall u,
s.(
r) !
u <>
None ->
exists set,
s.(
c) !
u =
Some set /\
set !
u =
Some tt).
Inductive postcondition4
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition4
(
CLASSIFY:
let '(
r,
c,
t,
back) :=
acc in
forall u succs v,
ginit !
u =
Some succs ->
r !
u <>
None ->
In v succs ->
In (
u,
v)
back \/
(
exists set,
c !
u =
Some set /\
set !
v =
Some tt) \/
directly_included r u v)
(
CROSS_UPWARDS:
let '(
r,
c,
t,
back) :=
acc in
forall u succs v set w,
ginit !
u =
Some succs ->
r !
u <>
None ->
In v succs -> ~
In (
u,
v)
back ->
c !
v =
Some set ->
set !
w =
Some tt ->
~
directly_included r u w ->
exists set',
c !
u =
Some set' /\
set' !
w =
Some tt)
(
CROSS_TARGETS_BLACK :
let '(
r,
c,
t,
back) :=
acc in
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
r !
v <>
None)
(
CROSS_REFL :
let '(
r,
c,
t,
back) :=
acc in
forall u,
r !
u <>
None ->
exists set,
c !
u =
Some set /\
set !
u =
Some tt).
Lemma transition_spec4:
forall dom_pre s (
INVARIANT :
invariant s),
invariant4 s ->
match transition dom_pre s with inr s' =>
invariant4 s' |
inl m =>
postcondition4 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
+
eauto.
+
eauto.
+
eauto.
+
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
inv WRK_NO_DUP;
assumption.
*
inv WRK_NO_DUP.
rewrite PTree.gsspec.
destruct (
peq u0 u).
--
subst u0.
contradiction H2.
apply InA_alt.
exists (
u,
n0,
l0,
post).
split; [
reflexivity|
assumption].
--
eauto with coqlib.
*
exploit WRK_DONE.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
specialize (
H2 _ H0 H3).
destruct H2.
--
left.
rewrite PTree.gso.
assumption.
intros contra.
subst v.
exploit WRK_NOT_BLACK.
left;
reflexivity.
congruence.
--
right;
assumption.
*
rewrite PTree.gsspec in H0.
destruct (
peq u0 u).
--
subst u0.
exploit CLASSIFY_GRAY.
left;
reflexivity.
intros (
l' &
H21 &
H22).
rewrite H21 in H.
inv H.
pose proof H1 as Hsucc.
apply H22 in H1; [|
intros contra;
contradiction].
destruct H1 as [
H1|[
H1|
H1]].
++
left;
assumption.
++
rewrite PTree.gss.
destruct ((
PTree.filter (
fun (
v :
positive) (
_ :
unit) =>
match (
PTree.set u (
n,
Pos.pred (
next s)) (
r s)) !
v with
|
Some i' =>
negb (
test_is_included i' (
n,
Pos.pred (
next s)))
|
None =>
false
end)
s_c) !
v)
eqn:
Hv.
---
rewrite PTree.gfilter in Hv.
rewrite H1 in Hv.
rewrite PTree.gsspec in Hv.
destruct (
peq v u).
+++
subst v.
right;
right.
apply directly_included_refl.
rewrite PTree.gss.
discriminate.
+++
unfold pre in *.
destruct (
s.(
r) !
v)
as [(
n1,
n2)|]
eqn:
Hrv.
***
destruct (
test_is_included (
n1,
n2) (
n,
Pos.pred (
next s)))
eqn:
Htest.
----
right;
right.
exists n, (
Pos.pred (
next s)),
n1,
n2.
split; [|
split].
++++
apply PTree.gss.
++++
rewrite PTree.gso by assumption.
assumption.
++++
apply test_is_included_spec;
assumption.
----
right;
left.
eexists.
split; [
reflexivity|].
rewrite PTree.gso by assumption.
rewrite PTree.gfilter.
rewrite H1.
unfold is_directly_included.
rewrite PTree.gss.
rewrite PTree.gso by assumption.
rewrite Hrv.
rewrite Htest.
reflexivity.
***
discriminate.
---
rewrite PTree.gfilter in Hv.
rewrite H1 in Hv.
rewrite PTree.gsspec in Hv.
destruct (
peq v u).
+++
subst v.
right;
right.
apply directly_included_refl.
rewrite PTree.gss.
discriminate.
+++
unfold pre in *.
destruct (
s.(
r) !
v)
as [(
n1,
n2)|]
eqn:
Hrv.
***
destruct (
test_is_included (
n1,
n2) (
n,
Pos.pred (
next s)))
eqn:
Htest.
----
right;
right.
exists n, (
Pos.pred (
next s)),
n1,
n2.
split; [|
split].
++++
apply PTree.gss.
++++
rewrite PTree.gso by assumption.
assumption.
++++
apply test_is_included_spec;
assumption.
----
discriminate.
***
exploit WRK_DONE.
left;
reflexivity.
intros (
l' &
H31 &
H32).
destruct (
H32 v).
congruence.
intros ?;
contradiction.
congruence.
left;
assumption.
++
destruct H1 as (
n1 &
n2 &
H11 &
H12).
right;
right.
do 4
eexists.
rewrite PTree.gss.
split; [
reflexivity|].
rewrite PTree.gso.
split; [
eassumption|].
split.
assumption.
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H11.
xomega.
exploit WRK_NOT_BLACK.
left;
reflexivity.
congruence.
--
exploit CLASSIFY_BLACK;
try eassumption.
intros [
H2|[
H2|
H2]].
++
left;
assumption.
++
right;
left.
rewrite PTree.gso by assumption.
assumption.
++
right;
right.
destruct H2 as (
n1 &
n2 &
m1 &
m2 &
H21 &
H22 &
H23).
exists n1,
n2,
m1,
m2.
rewrite PTree.gso by assumption.
rewrite PTree.gsspec.
destruct (
peq v u).
***
subst v.
exploit WRK_NOT_BLACK.
left;
reflexivity.
congruence.
***
split; [|
split];
assumption.
*
exploit CLASSIFY_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
H2 _ H0 H3)
as [
H4|[
H4|
H4]].
--
left;
assumption.
--
right;
left;
assumption.
--
right;
right.
destruct H4 as (
n1 &
n2 &
H41 &
H42).
exists n1,
n2.
rewrite PTree.gso.
split;
assumption.
exploit WRK_NOT_BLACK.
left;
reflexivity.
congruence.
*
rewrite PTree.gsspec.
destruct (
peq w u).
discriminate.
eauto with coqlib.
*
rewrite PTree.gsspec.
destruct (
peq v u).
discriminate.
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
subst u0.
eapply CROSS_TARGETS_BLACK_GRAY.
left;
reflexivity.
inv H.
rewrite PTree.gso in H0 by assumption.
rewrite PTree.gfilter in H0.
destruct (
s_c !
v)
as [[]|].
reflexivity.
discriminate.
--
eauto.
*
exploit CROSS_UPWARDS_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
rewrite PTree.gso in H5.
eauto.
exploit WRK_NOT_BLACK.
left;
reflexivity.
exploit WRK_DONE.
right;
eassumption.
intros (
l0' &
H71 &
H72).
rewrite H1 in H71.
inv H71.
specialize (
H72 v H0 H3).
destruct H72;
congruence.
*
rewrite PTree.gsspec in H0.
destruct (
peq u0 u).
--
subst u0.
exploit CROSS_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H61 &
H62).
rewrite H61 in H.
inv H.
rewrite PTree.gss.
eexists.
split.
reflexivity.
rewrite PTree.gsspec in H3.
destruct (
peq v u).
congruence.
rewrite PTree.gsspec.
destruct (
peq w u).
reflexivity.
rewrite PTree.gfilter.
erewrite H62 by eauto.
unfold is_directly_included.
rewrite PTree.gss.
specialize (
CROSS_TARGETS_BLACK_BLACK _ _ _ H3 H4).
rewrite PTree.gsspec.
destruct (
peq w u).
exploit WRK_NOT_BLACK.
left;
reflexivity.
congruence.
unfold pre in *.
destruct ((
r s) !
w)
as [(
m1,
m2)|]
eqn:
Hrw; [|
congruence].
destruct (
test_is_included (
m1,
m2) (
n,
Pos.pred (
next s)))
eqn:
Htest; [|
reflexivity].
contradiction H5.
do 4
eexists.
rewrite PTree.gss.
rewrite PTree.gso by assumption.
split; [
reflexivity|].
split; [
eassumption|].
apply test_is_included_spec;
assumption.
--
rewrite PTree.gso by assumption.
rewrite PTree.gsspec in H3.
destruct (
peq v u).
**
exploit WRK_NOT_BLACK;
eauto with coqlib.
intros.
exploit CLASSIFY_BLACK;
eauto.
intros [
H7|[
H7|
H7]].
contradiction.
destruct H7 as (
set' &
H71 &
H72).
specialize (
CROSS_TARGETS_BLACK_BLACK _ _ _ H71 H72).
congruence.
destruct H7 as (
_ &
_ &
n1 &
n2 &
_ &
H7 &
_).
congruence.
**
exploit CROSS_UPWARDS_BLACK;
eauto.
intros contra.
apply H5.
destruct contra as (
m1 &
m2 &
o1 &
o2 &
contra).
exists m1,
m2,
o1,
o2.
rewrite PTree.gso by assumption.
rewrite PTree.gso.
assumption.
exploit WRK_NOT_BLACK.
left;
reflexivity.
destruct contra as (
_ &
contra &
_).
congruence.
*
rewrite PTree.gsspec.
destruct (
peq u0 u).
--
subst u0.
eexists.
split; [
reflexivity|].
rewrite PTree.gss.
reflexivity.
--
rewrite PTree.gso in H by assumption.
eauto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
constructor; [|
assumption].
intros contra.
apply InA_alt in contra.
destruct contra as ((((
w,
m),
l'),
post) &
contra1 &
contra2).
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
eassumption.
intros (
H &
_).
congruence.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
_ _ _ _ _ _ _ INVARIANT _ _ _].
eauto.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
split; [
assumption|].
intros;
contradiction.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
split; [
assumption|].
intros;
contradiction.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
destruct H as [
H|[
H|
H]].
++
inv H.
rewrite PTree.gempty in H0.
discriminate.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
split; [
assumption|].
intros;
contradiction.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
constructor;
simpl;
intros.
**
inv WRK_NO_DUP.
constructor; [|
assumption].
intros contra;
apply H1.
apply InA_alt in contra.
apply InA_alt.
destruct contra as [(((
w,
m),
l'),
post)
contra].
exists (
w,
m,
l',
post).
assumption.
**
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
destruct H.
---
inv H.
exploit WRK_DONE.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
+++
left;
congruence.
+++
apply H2.
assumption.
intros contra.
destruct contra;
congruence.
---
eauto with coqlib.
**
eauto.
**
destruct H.
---
inv H.
exploit CLASSIFY_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
+++
subst v0.
right;
left.
destruct (
CROSS_REFL v)
as (
set &
H3 &
H4);
try congruence.
rewrite H3.
apply union_strict_correct.
left;
assumption.
+++
edestruct H2 as [
H3|[
H3|
H3]].
eassumption.
intros contra;
destruct contra;
congruence.
left;
assumption.
right;
left.
destruct (
s.(
c) !
v).
rewrite union_strict_correct.
right;
assumption.
assumption.
right;
right;
assumption.
---
eauto with coqlib.
**
destruct H.
---
inv H.
destruct (
s.(
c) !
v)
eqn:
Heqc.
apply union_strict_correct in H0.
destruct H0.
eauto.
eauto with coqlib.
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
destruct H.
---
inv H.
exploit CROSS_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
subst v0.
rewrite H4.
apply union_strict_correct.
left;
assumption.
destruct (
s.(
c) !
v)
eqn:
Heqc.
+++
apply union_strict_correct.
right.
eapply H2;
eauto.
intros contra;
destruct contra;
congruence.
+++
eapply H2;
eauto.
intros contra;
destruct contra;
congruence.
---
eauto with coqlib.
**
eauto.
**
eauto.
--
constructor;
simpl;
intros.
++
inv WRK_NO_DUP.
constructor; [|
assumption].
intros contra;
apply H1.
apply InA_alt in contra.
apply InA_alt.
destruct contra as [(((
w,
m),
l'),
post)
contra].
exists (
w,
m,
l',
post).
assumption.
++
destruct H.
inv H.
eauto with coqlib.
eauto with coqlib.
++
destruct H.
**
inv H.
exploit WRK_DONE.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
+++
right;
left;
congruence.
+++
destruct (
H2 v0).
assumption.
intros contra;
destruct contra;
congruence.
left;
assumption.
right;
right;
assumption.
**
exploit WRK_DONE.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
H2 _ H0 H3).
left;
assumption.
right;
right;
assumption.
++
exploit CLASSIFY_BLACK;
eauto.
intros [
H2|[
H2|
H2]];
eauto.
++
destruct H.
**
inv H.
exploit CLASSIFY_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
---
left;
left.
congruence.
---
edestruct H2 as [
H3|[
H3|
H3]];
eauto.
intros contra;
destruct contra;
congruence.
**
exploit CLASSIFY_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
specialize (
H2 _ H0 H3).
destruct H2 as [
H2|[
H2|
H2]];
eauto.
++
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
++
eauto.
++
destruct H.
---
inv H.
exploit CROSS_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v0 v).
subst v0.
contradiction H3.
left;
reflexivity.
eapply H2;
eauto.
intros contra;
destruct contra;
congruence.
---
exploit CROSS_UPWARDS_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
eauto.
++
eauto.
++
eauto.
Qed.
Lemma initial_state_spec4:
invariant4 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
repeat constructor.
intros contra;
inversion contra.
+
rewrite PTree.gempty.
reflexivity.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros.
contradiction.
+
rewrite PTree.gempty in H0.
contradiction.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros.
contradiction.
+
destruct H;
inv H.
rewrite PTree.gempty in H0.
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros.
contradiction.
+
rewrite PTree.gempty in H3.
discriminate.
+
rewrite PTree.gempty in H.
contradiction.
-
constructor;
simpl;
intros.
+
repeat constructor.
+
contradiction.
+
contradiction.
+
rewrite PTree.gempty in H0.
contradiction.
+
contradiction.
+
contradiction.
+
rewrite PTree.gempty in H.
discriminate.
+
contradiction.
+
rewrite PTree.gempty in H3.
discriminate.
+
rewrite PTree.gempty in H.
contradiction.
Qed.
Inductive invariant2 (
s:
state) :
Prop :=
Invariant2
(
REACHABLE_GRAY_GRAY :
Sorted (
fun '(
u,
_,
_,
_) '(
v,
_,
_,
_) =>
exists succs,
ginit !
v =
Some succs /\
In u succs /\ ~
In (
v,
u)
s.(
back))
s.(
wrk))
(
REACHABLE_GRAY_BLACK:
Sorted (
fun '(
_,
n,
_,
_) '(
u,
m,
_,
_) =>
forall v n1 n2,
s.(
r) !
v =
Some (
n1,
n2) ->
m <=
n1 <
n ->
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u v)
s.(
wrk))
(
REACHABLE_GRAY_BLACK_LAST:
forall u n l post v n1 n2 wrk',
s.(
wrk) = (
u,
n,
l,
post) ::
wrk' ->
s.(
r) !
v =
Some (
n1,
n2) -> (
n <=
n1)%
positive ->
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u v)
(
REACHABLE:
forall u v n1 n2 m1 m2,
s.(
r) !
u =
Some (
n1,
n2) ->
s.(
r) !
v =
Some (
m1,
m2) ->
is_included (
m1,
m2) (
n1,
n2) ->
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u v)
(
PREORDER_GRAY_GRAY :
Sorted (
fun '(
_,
n,
_,
_) '(
_,
m,
_,
_) => (
m <
n)%
positive)
s.(
wrk))
(
PREORDER_GRAY_BLACK :
forall u n l post v n1 n2,
In (
u,
n,
l,
post)
s.(
wrk) ->
s.(
r) !
v =
Some (
n1,
n2) -> (
n <
n1 \/
n2 <
n)%
positive)
(
CASES:
forall u v n1 n2 m1 m2,
s.(
r) !
u =
Some (
n1,
n2) ->
s.(
r) !
v =
Some (
m1,
m2) ->
m2 <
n1 \/
n2 <
m1
\/
is_included (
m1,
m2) (
n1,
n2) \/
is_included (
n1,
n2) (
m1,
m2))
(
BACK_NOT_WHITE :
forall u v,
In (
u,
v)
s.(
back) ->
s.(
gr) !
u =
None /\
s.(
gr) !
v =
None).
Inductive postcondition2
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition2
(
REACHABLE:
let '(
r,
c,
t,
back) :=
acc in
forall u v n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) ->
r !
v =
Some (
m1,
m2) ->
is_included (
m1,
m2) (
n1,
n2) ->
reduced_reachable ginit back u v)
(
CASES:
let '(
r,
c,
t,
back) :=
acc in
forall u v n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) ->
r !
v =
Some (
m1,
m2) ->
m2 <
n1 \/
n2 <
m1
\/
is_included (
m1,
m2) (
n1,
n2)
\/
is_included (
n1,
n2) (
m1,
m2)) .
Lemma HdRel_impl :
forall {
A} (
R1 R2 :
A ->
A ->
Prop)
a (
l :
list A)
(
R_impl :
forall y,
In y l ->
R1 a y ->
R2 a y) (
l_Sorted :
HdRel R1 a l),
HdRel R2 a l.
Proof.
intros. destruct l_Sorted; constructor.
eauto with coqlib.
Qed.
Lemma Sorted_impl :
forall {
A} (
R1 R2 :
A ->
A ->
Prop) (
l :
list A)
(
R_impl :
forall x y,
In x l ->
In y l ->
R1 x y ->
R2 x y) (
l_Sorted :
Sorted R1 l),
Sorted R2 l.
Proof.
intros.
induction l_Sorted.
-
constructor.
-
constructor.
+
eauto with coqlib.
+
apply (
HdRel_impl R1);
eauto with coqlib.
Qed.
Lemma Forall_impl_in :
forall {
A} (
P Q:
A->
Prop)
l,
(
forall a :
A,
In a l ->
P a ->
Q a) ->
Forall P l ->
Forall Q l.
Proof.
intros. induction H0.
- constructor.
- constructor; eauto with coqlib.
Qed.
Lemma StronglySorted_impl :
forall {
A} (
R1 R2 :
A ->
A ->
Prop) (
l :
list A)
(
R_impl :
forall x y,
In x l ->
In y l ->
R1 x y ->
R2 x y) (
l_Sorted :
StronglySorted R1 l),
StronglySorted R2 l.
Proof.
intros.
induction l_Sorted.
-
constructor.
-
constructor.
+
eauto with coqlib.
+
apply (
Forall_impl_in (
R1 a));
eauto with coqlib.
Qed.
Lemma Sorted_proj :
forall {
A B} (
f :
A ->
B) (
R :
A ->
A ->
Prop) (
l1 l2 :
list A),
(
forall a1 a2 a3 a4,
f a1 =
f a2 ->
f a3 =
f a4 ->
R a1 a3 ->
R a2 a4) ->
eqlistA (
fun x y =>
f x =
f y)
l1 l2 ->
Sorted R l1 ->
Sorted R l2.
Proof.
intros. revert dependent l2.
induction H1; intros.
- inv H0. constructor.
- inv H2. constructor. eauto.
inv H0; inv H7. constructor.
constructor; eauto.
Qed.
Lemma eqlistA_refl :
forall {
A} (
eqA :
A ->
A ->
Prop)
l,
Reflexive eqA ->
eqlistA eqA l l.
Proof.
induction l; constructor; eauto.
Qed.
Lemma transition_spec2:
forall dom_pre s (
INVARIANT :
invariant s) (
INVARIANT4 :
invariant4 s),
invariant2 s ->
match transition dom_pre s with inr s' =>
invariant2 s' |
inl m =>
postcondition2 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
+
eapply black_reduced_reachable_bis_is_reduced_reachable;
eauto.
+
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
inversion REACHABLE_GRAY_GRAY;
assumption.
*
inv REACHABLE_GRAY_BLACK.
eapply Sorted_impl;
try eassumption.
intros (((
v,
n1),
l1),
post1) (((
w,
n2),
l2),
post2).
intros.
rewrite PTree.gsspec in H4.
destruct (
peq v0 u).
--
inv H4.
apply Sorted_StronglySorted in PREORDER_GRAY_GRAY.
++
inv PREORDER_GRAY_GRAY.
rewrite Forall_forall in H8.
specialize (
H8 _ H).
simpl in H8.
xomega.
++
intros (((
_,
m1),
_),
_) (((
_,
m2),
_),
_) (((
_,
m3),
_),
_).
eauto using Pos.lt_trans.
--
apply black_reduced_reachable_bis_monotone.
eauto.
*
rewrite PTree.gsspec in H0.
destruct (
peq v u).
--
subst v.
inv REACHABLE_GRAY_GRAY.
inv H5.
destruct H2 as (
succs &
H21 &
H22 &
H23).
econstructor;
try eassumption.
rewrite PTree.gss.
discriminate.
constructor.
--
assert (
n1 <
n \/
n <=
n1)
by xomega.
destruct H2.
++
inv REACHABLE_GRAY_BLACK.
inv H6.
apply black_reduced_reachable_bis_monotone.
eauto.
++
inv REACHABLE_GRAY_GRAY.
inv H6.
destruct H3 as (
succs &
H31 &
H32 &
H33).
econstructor;
eauto.
rewrite PTree.gss;
discriminate.
apply black_reduced_reachable_bis_monotone.
eauto.
*
rewrite PTree.gsspec in H,
H0.
destruct (
peq u0 u), (
peq v u).
--
subst.
constructor.
--
subst u0.
apply black_reduced_reachable_bis_monotone.
eapply REACHABLE_GRAY_BLACK_LAST.
reflexivity.
eassumption.
inv H.
xomega.
--
subst v.
inv H0.
exploit PREORDER_GRAY_BLACK.
left;
reflexivity.
eassumption.
intros.
destruct H0.
xomega.
destruct INVARIANT as [
_ _ INVARIANT _ _ _ _ _ _ _ _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
xomega.
--
apply black_reduced_reachable_bis_monotone.
eauto.
*
inversion PREORDER_GRAY_GRAY;
assumption.
*
rewrite PTree.gsspec in H0.
destruct (
peq v u).
--
inv H0.
left.
apply Sorted_StronglySorted in PREORDER_GRAY_GRAY.
++
inv PREORDER_GRAY_GRAY.
rewrite Forall_forall in H3.
apply (
H3 _ H).
++
intros (((
_,
m1),
_),
_) (((
_,
m2),
_),
_) (((
_,
m3),
_),
_).
eauto using Pos.lt_trans.
--
eauto with coqlib.
*
rewrite PTree.gsspec in H,
H0.
destruct (
peq u0 u), (
peq v u).
--
inv H.
inv H0.
right;
right;
left.
split;
reflexivity.
--
subst u0.
inv H.
exploit PREORDER_GRAY_BLACK.
left;
reflexivity.
eassumption.
intros [
H|
H].
++
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H0.
right;
right;
left.
xomega.
++
left.
xomega.
--
subst v.
inv H0.
exploit PREORDER_GRAY_BLACK.
left;
reflexivity.
eassumption.
intros [
H1|
H1].
++
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H.
right;
right;
right.
xomega.
++
right;
left.
xomega.
--
eauto.
*
eauto with coqlib.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
constructor.
assumption.
constructor.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l' &
H &
H1 &
H2).
exists l'.
split; [|
split];
try eassumption.
apply H2.
left;
reflexivity.
intros contra.
apply BACK_NOT_WHITE in contra.
destruct contra as (
_ &
contra).
congruence.
--
constructor.
assumption.
constructor.
intros.
eapply REACHABLE_GRAY_BLACK_LAST.
reflexivity.
eassumption.
apply H0.
--
inv H.
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H0.
xomega.
--
eauto.
--
constructor.
assumption.
constructor.
destruct INVARIANT as [
_ _ INVARIANT _ _ _ _ _ _ _ _].
eapply INVARIANT.
rewrite HH.
left;
reflexivity.
--
destruct H as [
H | [
H|
H]].
++
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H0.
inv H;
xomega.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
exploit BACK_NOT_WHITE.
eassumption.
intros (
H1 &
H2).
rewrite 2!
PTree.grspec.
destruct (
PTree.elt_eq u0 v), (
PTree.elt_eq v0 v);
split;
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
inv REACHABLE_GRAY_GRAY.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
inv REACHABLE_GRAY_BLACK.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
inv H.
eauto.
**
eauto.
**
inv PREORDER_GRAY_GRAY.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
eauto.
++
constructor;
simpl;
intros.
**
inv REACHABLE_GRAY_GRAY.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
inv REACHABLE_GRAY_BLACK.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
inv H.
eauto.
**
eauto.
**
inv PREORDER_GRAY_GRAY.
constructor.
assumption.
inv H2;
constructor;
assumption.
**
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
eauto.
--
constructor;
simpl;
intros.
++
inv REACHABLE_GRAY_GRAY.
constructor.
**
eapply Sorted_impl;
try eassumption.
intros (((
x,
n1),
l1),
post1) (((
y,
n2),
l2),
post2).
intros.
destruct H3 as (
succs' &
H31 &
H32 &
H33).
exists succs'.
split; [
assumption|].
split; [
assumption|].
intros contra.
destruct contra; [|
contradiction].
inv H3.
destruct INVARIANT4 as [
INVARIANT4 _ _ _ _ _ _ _ _].
rewrite HH in INVARIANT4.
inv INVARIANT4.
apply H5.
apply InA_alt.
eexists (
_,
_,
_,
_).
split.
reflexivity.
eassumption.
**
destruct l as [|(((
w,
m),
l),
post)].
constructor.
inv H2.
destruct H0 as (
succs' &
H01 &
H02 &
H03).
constructor.
exists succs'.
split; [
assumption|].
split; [
assumption|].
intros contra.
destruct contra; [|
contradiction].
inv H.
destruct INVARIANT4 as [
INVARIANT4 _ _ _ _ _ _ _ _].
rewrite HH in INVARIANT4.
inv INVARIANT4.
apply H2.
apply InA_alt.
eexists (
_,
_,
_,
_).
split.
reflexivity.
left;
reflexivity.
++
inv REACHABLE_GRAY_BLACK.
constructor.
**
eapply Sorted_impl;
try eassumption.
intros (((
x,
n1),
l1),
post1) (((
y,
n2),
l2),
post2).
intros.
apply black_reduced_reachable_bis_back;
eauto.
**
destruct l as [|(((
w,
m),
l),
post)].
constructor.
inv H2.
constructor.
eauto using black_reduced_reachable_bis_back.
++
inv H.
eauto using black_reduced_reachable_bis_back.
++
eauto using black_reduced_reachable_bis_back.
++
inv PREORDER_GRAY_GRAY.
constructor.
assumption.
inv H2;
constructor;
assumption.
++
destruct H.
**
inv H.
eauto with coqlib.
**
eauto with coqlib.
++
eauto.
++
destruct H.
**
inv H.
split; [|
congruence].
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
H &
_).
assumption.
**
eauto.
Qed.
Lemma initial_state_spec2:
invariant2 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
repeat constructor.
+
repeat constructor.
+
rewrite PTree.gempty in H0.
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
repeat constructor.
+
rewrite PTree.gempty in H0.
discriminate.
+
rewrite PTree.gempty in H0.
discriminate.
+
contradiction.
-
constructor;
simpl;
intros.
+
constructor.
+
constructor.
+
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
constructor.
+
contradiction.
+
rewrite PTree.gempty in H0.
discriminate.
+
contradiction.
Qed.
Inductive invariant3 (
s:
state) :
Prop :=
Invariant3
(
CROSS_GRAY :
forall u n l s_c s_t v,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
s_c !
v =
Some tt ->
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u v)
(
CROSS:
forall u set v,
s.(
c) !
u =
Some set ->
set !
v =
Some tt ->
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u v)
(
BACK_REVERSE_WRK :
StronglySorted (
fun '(
u,
_,
_,
_) '(
v,
_,
_,
_) => ~
In (
v,
u)
s.(
back))
s.(
wrk))
(
WRK_BACK_NOT_BLACK :
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v,
In v l' ->
In (
u,
v)
s.(
back) ->
s.(
r) !
v =
None)).
Inductive postcondition3
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition3
(
CROSS:
let '(
r,
c,
t,
back) :=
acc in
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
reduced_reachable ginit back u v).
Lemma transition_spec3:
forall dom_pre s (
INVARIANT :
invariant s)
(
INVARIANT2 :
invariant2 s)
(
INVARIANT4 :
invariant4 s),
invariant3 s ->
match transition dom_pre s with inr s' =>
invariant3 s' |
inl m =>
postcondition3 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
eapply black_reduced_reachable_bis_is_reduced_reachable.
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
apply black_reduced_reachable_bis_monotone.
eauto.
*
apply black_reduced_reachable_bis_monotone.
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
++
subst u0.
inv H.
rewrite PTree.gsspec in H0.
destruct (
peq v u).
**
subst v.
constructor.
**
eapply CROSS_GRAY.
left;
reflexivity.
rewrite PTree.gfilter in H0.
destruct (
s_c !
v)
as [[]|]; [
reflexivity|
discriminate].
++
eauto.
*
inv BACK_REVERSE_WRK.
assumption.
*
exploit WRK_BACK_NOT_BLACK.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
rewrite PTree.gso.
apply H2;
assumption.
inv BACK_REVERSE_WRK.
rewrite Forall_forall in H7.
apply H7 in H.
congruence.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
destruct H as [
H|[
H|
H]].
++
inv H.
rewrite PTree.gempty in H0.
discriminate.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
constructor.
assumption.
apply Forall_forall.
intros (((
w,
m),
l'),
post')
H.
intros contra.
destruct INVARIANT2 as [
_ _ _ _ _ _ _ INVARIANT2].
apply INVARIANT2 in contra.
destruct contra as (
_ &
contra).
congruence.
--
destruct H as [
H|[
H|
H]].
++
inv H.
exists l0.
split.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
eauto.
intros.
destruct INVARIANT2 as [
_ _ _ _ _ _ _ INVARIANT2].
apply INVARIANT2 in H0.
destruct H0 as (
H0 &
_).
congruence.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
destruct H.
---
inv H.
exploit WRK_BACK_NOT_BLACK.
left;
reflexivity.
intros (
l' &
H &
H1).
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H21 &
_ &
H22).
rewrite H21 in H.
inv H.
destruct (
s.(
c) !
v)
eqn:
Heqc.
***
apply union_strict_correct in H0.
destruct H0.
----
eapply black_reduced_reachable_bis_pred.
eassumption.
apply H22.
left;
reflexivity.
congruence.
intros contra.
rewrite H1 in Heqo0.
discriminate.
apply H22;
left;
reflexivity.
assumption.
eauto.
----
eauto with coqlib.
***
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
inv BACK_REVERSE_WRK.
constructor;
assumption.
**
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
++
constructor;
simpl;
intros.
**
destruct H as [
H|
H].
---
inv H.
exploit WRK_BACK_NOT_BLACK.
left;
reflexivity.
intros (
l' &
H &
H1).
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H21 &
_ &
H22).
rewrite H21 in H.
inv H.
destruct (
s.(
c) !
v)
as [
set|]
eqn:
Heq.
+++
apply union_strict_correct in H0.
destruct H0.
***
eapply black_reduced_reachable_bis_pred.
eassumption.
apply H22.
left;
reflexivity.
congruence.
intros contra.
rewrite H1 in Heqo0.
discriminate.
apply H22;
left;
reflexivity.
assumption.
eauto.
***
eauto with coqlib.
+++
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
inv BACK_REVERSE_WRK.
constructor;
assumption.
**
destruct H.
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
--
constructor;
simpl;
intros.
++
apply black_reduced_reachable_bis_back; [|
congruence].
destruct H as [
H|
H].
**
inv H.
eauto with coqlib.
**
eauto with coqlib.
++
apply black_reduced_reachable_bis_back; [|
congruence].
eauto with coqlib.
++
inv BACK_REVERSE_WRK.
constructor.
**
eapply StronglySorted_impl; [|
eassumption].
intros (((
x,
n1),
l1),
post1) (((
y,
n2),
l2),
post2).
intros.
intros contra.
destruct contra; [|
contradiction].
inv H4.
destruct INVARIANT4 as [
INVARIANT4 _ _ _ _ _ _ _ _].
rewrite HH in INVARIANT4.
inv INVARIANT4.
apply H6.
apply InA_alt.
eexists (
_,
_,
_,
_).
split; [
reflexivity|
eassumption].
**
rewrite Forall_forall in * |- *.
intros (((
w,
m),
l'),
post')
H3 contra.
specialize (
H2 _ H3).
destruct contra; [|
contradiction].
inv H.
destruct INVARIANT4 as [
INVARIANT4 _ _ _ _ _ _ _ _].
rewrite HH in INVARIANT4.
inv INVARIANT4.
apply H4.
apply InA_alt.
eexists (
_,
_,
_,
_).
split; [
reflexivity|
eassumption].
++
destruct H.
**
inv H.
exploit WRK_BACK_NOT_BLACK.
left;
reflexivity.
intros (
l' &
H &
H1).
exists l'.
split; [
assumption|].
intros.
destruct H2.
inv H2.
assumption.
eauto.
**
exploit WRK_BACK_NOT_BLACK.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct H3.
inv H3.
assumption.
eauto.
Qed.
Lemma initial_state_spec3:
invariant3 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
destruct H;
inv H.
rewrite PTree.gempty in H0.
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
repeat constructor.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros.
contradiction.
-
constructor;
simpl;
intros.
+
contradiction.
+
rewrite PTree.gempty in H.
discriminate.
+
constructor.
+
contradiction.
Qed.
Inductive invariant5 (
s:
state) :
Prop :=
Invariant5
(
BLACK_IN_GRAPH :
forall u,
s.(
r) !
u <>
None ->
ginit !
u <>
None)
(
BLACK_REACHABLE_GRAY :
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
reachable ginit root u)
(
BLACK_REACHABLE_BLACK :
forall u,
s.(
r) !
u <>
None ->
reachable ginit root u)
(
OUT_NODES_BACK_GRAY :
forall u n l post,
In (
u,
n,
l,
post)
s.(
wrk) ->
exists l',
ginit !
u =
Some l' /\
forall v,
In v l' -> ~
In v l ->
ginit !
v =
None ->
In (
u,
v)
s.(
back))
(
CROSS_BLACK :
forall u,
s.(
c) !
u <>
None ->
s.(
r) !
u <>
None)
(
OUT_NODES_BACK_BLACK :
forall u succs v,
s.(
r) !
u <>
None ->
ginit !
u =
Some succs ->
In v succs ->
ginit !
v =
None ->
In (
u,
v)
s.(
back))
(
BACK_SOURCE_GRAY_OR_BLACK :
forall u v,
In (
u,
v)
s.(
back) ->
(
exists n l post,
In (
u,
n,
l,
post)
s.(
wrk)) \/
s.(
r) !
u <>
None)
(
BACK_BLACK :
forall u,
s.(
t) !
u <>
None <->
s.(
r) !
u <>
None)
(
BACK_IN_GRAPH :
forall u v,
In (
u,
v)
s.(
back) ->
exists succs,
ginit !
u =
Some succs /\
In v succs).
Inductive postcondition5
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition5
(
BLACK_IN_GRAPH :
let '(
r,
c,
t,
back) :=
acc in
forall u,
r !
u <>
None ->
ginit !
u <>
None)
(
BLACK_REACHABLE :
let '(
r,
c,
t,
back) :=
acc in
forall u,
r !
u <>
None ->
reachable ginit root u)
(
CROSS_BLACK :
let '(
r,
c,
t,
back) :=
acc in
forall u,
c !
u <>
None ->
r !
u <>
None)
(
OUT_NODES_BACK :
let '(
r,
c,
t,
back) :=
acc in
forall u succs v,
ginit !
u =
Some succs ->
In v succs ->
ginit !
v =
None ->
r !
u <>
None ->
In (
u,
v)
back)
(
BACK_SOURCE_BLACK :
let '(
r,
c,
t,
back) :=
acc in
forall u v,
In (
u,
v)
back ->
r !
u <>
None)
(
BACK_BLACK :
let '(
r,
c,
t,
back) :=
acc in
forall u,
t !
u <>
None <->
r !
u <>
None)
(
BACK_IN_GRAPH :
let '(
r,
c,
t,
back) :=
acc in
forall u v,
In (
u,
v)
back ->
exists succs,
ginit !
u =
Some succs /\
In v succs).
Lemma transition_spec5:
forall dom_pre s (
INVARIANT :
invariant s),
invariant5 s ->
match transition dom_pre s with inr s' =>
invariant5 s' |
inl m =>
postcondition5 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
+
eauto.
+
eauto.
+
eauto.
+
eauto.
+
apply BACK_SOURCE_GRAY_OR_BLACK in H.
destruct H; [|
assumption].
destruct H as (? & ? & ? &
H).
contradiction.
+
eauto.
+
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
subst u0.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l' &
H1 &
_).
congruence.
--
eauto.
*
eauto with coqlib.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
subst u0.
eauto with coqlib.
--
eauto.
*
eauto with coqlib.
*
rewrite PTree.gsspec.
destruct (
peq u0 u).
--
discriminate.
--
rewrite PTree.gso in H by assumption.
eauto.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
subst u0.
exploit OUT_NODES_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H31 &
H32).
rewrite H31 in H0.
inv H0.
eauto with coqlib.
--
eauto.
*
rewrite PTree.gsspec.
destruct (
peq u0 u).
--
right;
discriminate.
--
exploit BACK_SOURCE_GRAY_OR_BLACK;
try eassumption.
intros.
destruct H0 as [(
n1 &
l1 &
post1 &
H0) |
H0].
++
destruct H0; [
congruence|].
eauto.
++
right;
assumption.
*
rewrite 2!
PTree.gsspec.
destruct (
peq u0 u).
--
split;
discriminate.
--
eauto.
*
eauto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l' &
H &
_ &
H1).
eapply reachable_succ.
eauto with coqlib.
eassumption.
apply H1;
left;
reflexivity.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
eauto.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
eauto.
--
apply BACK_SOURCE_GRAY_OR_BLACK in H.
destruct H as [(
n1 &
l1 &
post1 &
H) |
H].
++
left.
eexists _,
_ ,
_.
right.
eassumption.
++
right;
assumption.
--
eauto.
--
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
exploit OUT_NODES_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
eapply H2;
eauto.
intros contra.
destruct contra; [|
contradiction].
subst v0.
eapply BLACK_IN_GRAPH;
try apply H3.
congruence.
---
eauto with coqlib.
**
eauto.
**
eauto.
**
apply BACK_SOURCE_GRAY_OR_BLACK in H.
destruct H as [(
n3 &
l1 &
post1 &
H) |
H].
---
left.
destruct H.
+++
inv H.
eexists _,
_,
_.
left.
reflexivity.
+++
eexists _,
_,
_.
right.
eassumption.
---
right;
assumption.
**
eauto.
**
eauto.
++
constructor;
simpl;
intros.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
exploit OUT_NODES_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
eapply H2;
eauto.
intros contra.
destruct contra; [|
contradiction].
subst v0.
eapply BLACK_IN_GRAPH;
try apply H3.
congruence.
---
eauto with coqlib.
**
eauto.
**
eauto.
**
apply BACK_SOURCE_GRAY_OR_BLACK in H.
destruct H as [(
n3 &
l1 &
post1 &
H) |
H].
---
left.
destruct H.
+++
inv H.
eexists _,
_,
_.
left.
reflexivity.
+++
eexists _,
_,
_.
right.
eassumption.
---
right;
assumption.
**
eauto.
**
eauto.
--
constructor;
simpl;
intros.
++
eauto.
++
destruct H as [
H|
H].
**
inv H.
eauto with coqlib.
**
eauto with coqlib.
++
eauto.
++
destruct H as [
H|
H].
**
inv H.
exploit OUT_NODES_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
destruct (
peq v v0).
left.
congruence.
right.
eapply H2;
eauto.
intros contra.
destruct contra;
contradiction.
**
exploit OUT_NODES_BACK_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
eauto.
++
eauto.
++
eauto.
++
destruct H.
**
inv H.
left.
eexists _,
_,
_.
left;
reflexivity.
**
apply BACK_SOURCE_GRAY_OR_BLACK in H.
destruct H as [(
n3 &
l1 &
post1 &
H) |
H].
---
left.
destruct H.
+++
inv H.
eexists _,
_,
_.
left.
reflexivity.
+++
eexists _,
_,
_.
right.
eassumption.
---
right;
assumption.
++
eauto.
++
destruct H as [
H|
H].
**
inv H.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l' &
H1 &
_ &
H2).
eexists.
split; [
eassumption|].
apply H2.
left;
reflexivity.
**
eauto.
Qed.
Lemma initial_state_spec5:
invariant5 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
rewrite PTree.gempty in H.
contradiction.
+
destruct H;
inv H.
constructor.
+
rewrite PTree.gempty in H.
contradiction.
+
destruct H;
inv H.
exists l.
split.
assumption.
intros;
contradiction.
+
rewrite PTree.gempty in H.
contradiction.
+
rewrite PTree.gempty in H.
contradiction.
+
contradiction.
+
rewrite 2!
PTree.gempty.
split;
contradiction.
+
contradiction.
-
constructor;
simpl;
intros.
+
rewrite PTree.gempty in H.
contradiction.
+
contradiction.
+
rewrite PTree.gempty in H.
contradiction.
+
contradiction.
+
rewrite PTree.gempty in H.
contradiction.
+
rewrite PTree.gempty in H.
contradiction.
+
contradiction.
+
rewrite 2!
PTree.gempty.
split;
contradiction.
+
contradiction.
Qed.
Section DOM_PRE.
Variable dom_pre :
node ->
Z.
Local Opaque ZSortWithIndex.merge.
Inductive invariant9 (
s:
state) :
Prop :=
Invariant9
(
T_DOM_PRE_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
s_t)
(
T_DOM_PRE_BLACK :
forall u set,
s.(
t) !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
T_SORTED_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z s_t)
(
T_SORTED_BLACK :
forall u set,
s.(
t) !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set).
Inductive postcondition9
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition9
(
T_DOM_PRE :
let '(
r,
c,
t,
back) :=
acc in
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
T_SORTED :
let '(
r,
c,
t,
back) :=
acc in
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set).
Lemma transition_spec9:
forall s,
invariant9 s ->
match transition dom_pre s with inr s' =>
invariant9 s' |
inl m =>
postcondition9 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
+
eauto.
+
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
eauto.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
++
subst u0.
inv H.
apply Forall_forall.
intros (
v,
n_v)
H.
apply filter_In in H.
destruct H as (
H &
_).
exploit T_DOM_PRE_GRAY.
left;
reflexivity.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
++
eauto.
*
eauto.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
++
subst u0.
inv H.
apply filter_sort with (
eqA:=
eq).
**
eauto.
**
split.
---
unfold Irreflexive,
complement.
intros (
_,
n1).
apply Z.lt_irrefl.
---
intros (
_,
n1) (
_,
n2) (
_,
n3).
apply Z.lt_trans.
**
intros (
v1,
n_v1) (
v2,
n_v2)
eq_v (
w1,
n_w1) (
w2,
n_w2)
eq_w.
inv eq_v.
inv eq_w.
reflexivity.
**
eauto.
++
eauto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
destruct H as [
H|[
H|
H]].
++
inv H.
constructor.
++
inv H.
eauto.
++
eauto.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
constructor.
++
inv H.
eauto.
++
eauto.
--
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
destruct H as [
H|
H].
---
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply Forall_forall.
intros (
w,
n_w)
H.
apply ZSortWithIndex.incl_merge in H.
apply in_app_iff in H.
destruct H as [
H|
H].
***
exploit T_DOM_PRE_BLACK.
eassumption.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
***
exploit T_DOM_PRE_GRAY.
left;
reflexivity.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
+++
eauto.
---
eauto.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply Sorted_LocallySorted_iff.
apply ZSortWithIndex.Sorted_merge.
***
apply Sorted_LocallySorted_iff.
eauto.
***
apply Sorted_LocallySorted_iff.
eauto.
+++
eauto.
---
eauto.
**
eauto.
++
constructor;
simpl;
intros.
**
destruct H as [
H|
H].
---
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply Forall_forall.
intros (
w,
n_w)
H.
apply ZSortWithIndex.incl_merge in H.
apply in_app_iff in H.
destruct H as [
H|
H].
***
exploit T_DOM_PRE_BLACK.
eassumption.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
***
exploit T_DOM_PRE_GRAY.
left;
reflexivity.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
+++
eauto.
---
eauto.
**
eauto.
**
destruct H as [
H|
H].
---
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply Sorted_LocallySorted_iff.
apply ZSortWithIndex.Sorted_merge.
***
apply Sorted_LocallySorted_iff.
eauto.
***
apply Sorted_LocallySorted_iff.
eauto.
+++
eauto.
---
eauto.
**
eauto.
--
constructor;
simpl;
intros.
++
destruct H as [
H|
H].
**
inv H.
apply Forall_forall.
intros (
w,
n_w)
H.
apply ZSortWithIndex.incl_merge in H.
simpl in H.
destruct H as [
H|
H].
---
inv H.
reflexivity.
---
exploit T_DOM_PRE_GRAY.
left;
reflexivity.
intros.
rewrite Forall_forall in H0.
apply (
H0 _ H).
**
eauto.
++
eauto.
++
destruct H as [
H|
H].
**
inv H.
apply Sorted_LocallySorted_iff.
apply ZSortWithIndex.Sorted_merge.
---
constructor.
---
apply Sorted_LocallySorted_iff.
eauto.
**
eauto.
++
eauto.
Qed.
Lemma initial_state_spec9:
invariant9 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
destruct H;
inv H.
constructor.
+
rewrite PTree.gempty in H.
discriminate.
+
destruct H;
inv H.
constructor.
+
rewrite PTree.gempty in H.
discriminate.
-
constructor;
simpl;
intros.
+
contradiction.
+
rewrite PTree.gempty in H.
discriminate.
+
contradiction.
+
rewrite PTree.gempty in H.
discriminate.
Qed.
Section DOM_PRE_HYPS.
Hypothesis dom_pre_inj :
forall u v,
reachable ginit root u ->
reachable ginit root v ->
dom_pre u =
dom_pre v ->
u =
v.
Inductive invariant6 (
s:
state) :
Prop :=
Invariant6
(
BACK_SOURCE_GRAY :
forall u n l s_c s_t v,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
In v (
List.map fst s_t) ->
exists w,
In (
w,
v)
s.(
back)
/\
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u w)
(
BACK_SOURCE :
forall u set v,
s.(
t) !
u =
Some set ->
In v (
List.map fst set) ->
exists w,
In (
w,
v)
s.(
back)
/\
black_reduced_reachable_bis ginit s.(
r)
s.(
back)
u w)
(
BACK_TARGETS :
forall u set v,
s.(
t) !
u =
Some set ->
In v (
map fst set) ->
~
cross_included s.(
r)
s.(
c)
u v)
(
BACK_UPWARDS_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v set w,
In v l' -> ~
In v l -> ~
In (
u,
v)
s.(
back) ->
s.(
t) !
v =
Some set ->
In w (
map fst set) ->
In w (
map fst s_t)))
(
BACK_UPWARDS_BLACK :
forall u succs v set w,
ginit !
u =
Some succs ->
s.(
r) !
u <>
None ->
In v succs -> ~
In (
u,
v)
s.(
back) ->
s.(
t) !
v =
Some set ->
In w (
map fst set) ->
~
cross_included s.(
r)
s.(
c)
u w ->
exists set',
s.(
t) !
u =
Some set' /\
In w (
map fst set'))
(
CLASSIFY_BACK_GRAY :
forall u n l s_c s_t,
In (
u,
n,
l, (
s_c,
s_t))
s.(
wrk) ->
exists l',
ginit!
u =
Some l' /\
(
forall v,
In v l' -> ~
In v l ->
In (
u,
v)
s.(
back) ->
In v (
map fst s_t)))
(
CLASSIFY_BACK_BLACK :
forall u v,
In (
u,
v)
s.(
back) ->
s.(
r)!
u <>
None ->
u =
v \/
exists set,
s.(
t) !
u =
Some set /\
In v (
map fst set)).
Inductive postcondition6
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition6
(
BACK_SOURCE :
let '(
r,
c,
t,
back) :=
acc in
forall u set v,
t !
u =
Some set ->
In v (
map fst set) ->
exists w,
In (
w,
v)
back
/\
reduced_reachable ginit back u w)
(
BACK_TARGETS :
let '(
r,
c,
t,
back) :=
acc in
forall u set v,
t !
u =
Some set ->
In v (
map fst set) ->
~
cross_included r c u v)
(
BACK_UPWARDS:
let '(
r,
c,
t,
back) :=
acc in
forall u succs v set w,
ginit !
u =
Some succs ->
r !
u <>
None ->
In v succs -> ~
In (
u,
v)
back ->
t !
v =
Some set ->
In w (
map fst set) ->
~
cross_included r c u w ->
exists set',
t !
u =
Some set' /\
In w (
map fst set'))
(
CLASSIFY_BACK :
let '(
r,
c,
t,
back) :=
acc in
forall u v,
In (
u,
v)
back ->
r !
u <>
None ->
u =
v \/
exists set,
t !
u =
Some set /\
In v (
List.map fst set)).
Lemma transition_spec6:
forall s (
INVARIANT :
invariant s) (
INVARIANT2 :
invariant2 s)
(
INVARIANT3 :
invariant3 s) (
INVARIANT4 :
invariant4 s)
(
INVARIANT5 :
invariant5 s) (
INVARIANT9 :
invariant9 s),
invariant6 s ->
match transition dom_pre s with inr s' =>
invariant6 s' |
inl m =>
postcondition6 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
+
exploit BACK_SOURCE;
try eassumption.
intros (
w &
H1 &
H2).
exists w.
split; [
assumption|].
eapply black_reduced_reachable_bis_is_reduced_reachable;
eassumption.
+
eauto.
+
eauto.
+
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
exploit BACK_SOURCE_GRAY.
right;
eassumption.
eassumption.
intros (
w &
H1 &
H2).
exists w.
split; [
assumption|].
apply black_reduced_reachable_bis_monotone.
assumption.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
++
subst u0.
assert (
exists w :
node,
In (
w,
v) (
back s) /\
black_reduced_reachable_bis ginit s.(
r) (
back s)
u w).
{
eapply BACK_SOURCE_GRAY.
left;
reflexivity.
inv H.
apply in_map_iff in H0.
destruct H0 as ((
v',
n_v) &
H0' &
H0).
simpl in H0'.
subst.
apply filter_In in H0.
destruct H0 as (
H0 &
_).
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
destruct H1 as (? & ? & ?).
eauto using black_reduced_reachable_bis_monotone.
++
exploit BACK_SOURCE;
try eassumption.
intros (
w &
H1 &
H2).
eauto using black_reduced_reachable_bis_monotone.
*
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
**
inv H.
apply in_map_iff in H0.
destruct H0 as ((
v',
n_v) &
H0' &
H0).
simpl in H0'.
subst.
apply filter_In in H0.
destruct H0 as (
H01 &
H02).
apply negb_true_iff,
not_true_iff_false in H02.
intros contra.
apply H02.
apply can_reach_spec.
rewrite PTree.gss;
discriminate.
assumption.
**
intros contra.
eapply BACK_TARGETS;
try eassumption.
destruct contra as (
set' &
w' &
contra1 &
contra2 &
n1 &
n2 &
m1 &
m2 &
contra3).
exists set',
w'.
rewrite PTree.gso in contra1.
split; [
assumption|].
split; [
assumption|].
exists n1,
n2,
m1,
m2.
rewrite PTree.gso in contra3.
rewrite PTree.gsspec in contra3.
destruct (
peq v u); [|
assumption].
impossible: is_included (n, Pos.pred (next s)) (n1, n1) *)
destruct contra3 as (
contra31 &
contra32 &
contra33 &
contra34).
destruct INVARIANT2 as [
_ _ _ _ _ INVARIANT2 _ _].
exploit INVARIANT2.
rewrite HH.
left;
reflexivity.
eassumption.
destruct INVARIANT as [
_ _ BELOW1 BELOW2 _ _ _ _ _ _ _].
exploit BELOW1.
rewrite HH.
left;
reflexivity.
apply BELOW2 in contra31.
inv contra32.
xomega.
destruct INVARIANT4
as [
_ WRK_NOT_BLACK _ _ _ _ CROSS_TARGETS_BLACK_BLACK _ _].
eapply CROSS_TARGETS_BLACK_BLACK in contra1;
try eassumption.
exploit WRK_NOT_BLACK.
rewrite HH.
left;
reflexivity.
congruence.
destruct INVARIANT4 as [
_ INVARIANT4 _ _ _ _ _ _ _].
exploit INVARIANT4.
rewrite HH.
left;
reflexivity.
intros.
intros contra4.
destruct INVARIANT5 as [
_ _ _ _ _ _ _ INVARIANT5 _].
eapply (
proj1 (
INVARIANT5 _));
try eassumption.
congruence.
*
exploit BACK_UPWARDS_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
rewrite PTree.gso in H5.
eauto.
destruct INVARIANT4 as [
_ WRK_NOT_BLACK WRK_DONE _ _ _ _ _ _].
exploit WRK_NOT_BLACK.
rewrite HH.
left;
reflexivity.
exploit WRK_DONE.
rewrite HH.
right;
eassumption.
intros (
l0' &
H71 &
H72).
rewrite H1 in H71.
inv H71.
specialize (
H72 v H0 H3).
destruct H72;
congruence.
*
rewrite PTree.gsspec in H0.
destruct (
peq u0 u).
--
subst u0.
exploit BACK_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H61 &
H62).
rewrite H61 in H.
inv H.
rewrite PTree.gss.
eexists.
split.
reflexivity.
rewrite PTree.gsspec in H3.
destruct (
peq v u).
congruence.
exploit H62;
eauto.
intros H7.
apply in_map_iff in H7.
destruct H7 as ((
w',
n_w) &
H7' &
H7).
simpl in H7'.
subst.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply filter_In.
split.
eassumption.
apply negb_true_iff,
not_true_iff_false.
rewrite can_reach_spec.
assumption.
rewrite PTree.gss.
discriminate.
--
rewrite PTree.gso by assumption.
rewrite PTree.gsspec in H3.
destruct (
peq v u).
**
destruct INVARIANT4 as [
_ WRK_NOT_BLACK _ CLASSIFY_BLACK _ _ CROSS_TARGETS_BLACK_BLACK _ _].
exploit WRK_NOT_BLACK;
eauto.
rewrite HH.
left;
reflexivity.
intros.
exploit CLASSIFY_BLACK;
eauto.
intros [
H8|[
H8|
H8]].
contradiction.
destruct H8 as (
set' &
H81 &
H82).
specialize (
CROSS_TARGETS_BLACK_BLACK _ _ _ H81 H82).
congruence.
destruct H8 as (
_ &
_ &
n1 &
n2 &
_ &
H8 &
_).
congruence.
**
exploit BACK_UPWARDS_BLACK;
eauto.
intros contra.
apply H5.
destruct contra as (
set' &
w' &
contra1 &
contra2 &
n1' &
n2 &
m1 &
m2 &
contra3).
exists set',
w'.
rewrite PTree.gso by assumption.
split; [
assumption|].
split; [
assumption|].
exists n1',
n2,
m1,
m2.
rewrite PTree.gso.
rewrite PTree.gso.
assumption.
destruct INVARIANT4 as [
_ INVARIANT4 _ _ _ _ _ _ _].
exploit INVARIANT4.
rewrite HH.
left;
reflexivity.
destruct contra3 as (
_ &
contra3 &
_).
congruence.
destruct INVARIANT4 as [
_ INVARIANT4 _ _ _ _ _ _ _].
exploit INVARIANT4.
rewrite HH.
left;
reflexivity.
destruct contra3 as (
contra3 &
_ &
_).
congruence.
*
eauto.
*
rewrite PTree.gsspec.
destruct (
peq u0 u).
++
subst.
destruct (
peq u v).
**
left;
assumption.
**
right.
eexists.
split; [
reflexivity|].
exploit CLASSIFY_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H2 &
H3).
destruct INVARIANT5 as [
_ _ _ _ _ _ _ _ INVARIANT5].
destruct (
INVARIANT5 _ _ H)
as (
succs &
H41 &
H42).
rewrite H41 in H2.
inv H2.
exploit H3;
eauto.
intros.
apply in_map_iff in H1.
destruct H1 as ((
v',
n_v) &
H1' &
H1).
simpl in H1'.
subst.
apply in_map_iff.
eexists (
_,
_).
split; [
reflexivity|].
apply filter_In.
split; [
eassumption|].
apply negb_true_iff.
unfold can_reach.
rewrite PTree.gso by congruence.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l'' &
H51 &
H52).
rewrite H51 in H41.
inv H41.
rewrite H52 by assumption.
reflexivity.
++
rewrite PTree.gso in H0 by assumption.
eauto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
destruct H as [
H|[
H|
H]].
++
inv H.
contradiction H0.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
split; [
assumption|].
intros;
contradiction.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT as [
INVARIANT _ _ _ _ _ _ _ _ _ _].
apply INVARIANT in Heqo.
exists l0.
split; [
assumption|].
intros;
contradiction.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
destruct H.
---
inv H.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l' &
H &
H1).
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H21 &
_ &
H22).
rewrite H21 in H.
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply in_map_iff in H0.
destruct H0 as ((
v0',
n_v0) &
H0' &
H0).
simpl in H0'.
subst.
apply ZSortWithIndex.incl_merge in H0.
rewrite in_app_iff in H0.
destruct H0 as [
H0|
H0].
***
exploit BACK_SOURCE;
try eassumption.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
w &
H2 &
H3).
exists w.
split; [
assumption|].
eapply black_reduced_reachable_bis_pred.
eassumption.
apply H22.
left;
reflexivity.
congruence.
intros contra.
rewrite H1 in Heqo0.
discriminate.
apply H22;
left;
reflexivity.
assumption.
assumption.
***
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
+++
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
eauto.
**
destruct H.
---
inv H.
exploit BACK_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
apply in_map_iff in H5.
destruct H5 as ((
w',
n_w) &
H5' &
H5).
simpl in H5'.
subst.
destruct (
peq v0 v).
subst v0.
rewrite H4.
+++
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
left;
eassumption.
+++
destruct (
s.(
t) !
v)
eqn:
Heqt.
***
exploit H2;
eauto.
intros [
contra|
contra];
congruence.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros H6.
apply in_map_iff in H6.
destruct H6 as ((
w',
n_w') &
H6' &
H6).
simpl in H6'.
subst.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
eassumption.
***
eapply H2;
eauto.
intros contra;
destruct contra;
congruence.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
---
eauto with coqlib.
**
eauto.
**
destruct H.
---
inv H.
exploit CLASSIFY_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H &
H1).
exists l'.
split; [
assumption|].
intros.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
exploit H1;
try eassumption.
intros [
contra|
contra]; [|
contradiction].
subst.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l'' &
H51 &
H52).
rewrite H51 in H.
inv H.
rewrite H52 in Heqo0 by assumption.
discriminate.
intros.
apply in_map_iff in H4.
destruct H4 as ((
v0',
n_v0) &
H4' &
H4).
simpl in H4'.
subst.
apply in_map_iff.
eexists (
_,
_).
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
eassumption.
+++
apply H1;
try assumption.
intros contra.
destruct contra; [|
contradiction].
subst.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l'' &
H41 &
H42).
rewrite H41 in H.
inv H.
rewrite H42 in Heqo0 by assumption.
discriminate.
---
eauto with coqlib.
**
eauto.
++
constructor;
simpl;
intros.
**
destruct H.
---
inv H.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l' &
H &
H1).
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H21 &
_ &
H22).
rewrite H21 in H.
inv H.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
apply in_map_iff in H0.
destruct H0 as ((
v0',
n_v0) &
H0' &
H0).
simpl in H0'.
subst.
apply ZSortWithIndex.incl_merge in H0.
rewrite in_app_iff in H0.
destruct H0.
***
exploit BACK_SOURCE;
try eassumption.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
w &
H2 &
H3).
exists w.
split; [
assumption|].
eapply black_reduced_reachable_bis_pred.
eassumption.
apply H22.
left;
reflexivity.
congruence.
intros contra.
rewrite H1 in Heqo0.
discriminate.
apply H22;
left;
reflexivity.
assumption.
assumption.
***
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
+++
eauto with coqlib.
---
eauto with coqlib.
**
eauto.
**
eauto.
**
destruct H.
---
inv H.
exploit BACK_UPWARDS_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
apply in_map_iff in H5.
destruct H5 as ((
w',
n_w) &
H5' &
H5).
simpl in H5'.
subst.
destruct (
peq v0 v).
subst v0.
rewrite H4.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
left;
eassumption.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
exploit H2;
eauto.
intros contra;
destruct contra;
congruence.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros H6.
apply in_map_iff in H6.
destruct H6 as ((
w',
n_w') &
H6' &
H6).
simpl in H6'.
subst.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
eassumption.
+++
eapply H2;
eauto.
intros contra;
destruct contra;
congruence.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
---
eauto with coqlib.
**
eauto.
**
destruct H.
---
inv H.
exploit CLASSIFY_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H &
H1).
exists l'.
split; [
assumption|].
intros.
destruct (
s.(
t) !
v)
eqn:
Heqt.
+++
exploit H1;
try eassumption.
intros [
contra|
contra]; [|
contradiction].
subst.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l'' &
H51 &
H52).
rewrite H51 in H.
inv H.
rewrite H52 in Heqo0 by assumption.
discriminate.
intros.
apply in_map_iff in H4.
destruct H4 as ((
v0',
n_v0) &
H4' &
H4).
simpl in H4'.
subst.
apply in_map_iff.
eexists (
_,
_).
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
destruct INVARIANT9 as [
_ INVARIANT9 _ _].
exploit INVARIANT9;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
assert (
exists x',
In (
x',
x1)
s.(
back))
as Hc'.
{
exploit BACK_SOURCE;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hc'
as (
x' &
Hc').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hc')
as (
succs &
H81 &
H82).
eapply reachable_succ;
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hc'.
destruct Hc'
as [(? & ? & ? &
Hc')|
Hc'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
assert (
reachable ginit root x2)
as Hd.
{
assert (
exists x',
In (
x',
x2)
s.(
back))
as Hd'.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
H7 &
_).
eexists;
eassumption.
}
destruct Hd'
as (
x' &
Hd').
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
eassumption.
+++
apply H1;
try assumption.
intros contra.
destruct contra; [|
contradiction].
subst.
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l'' &
H41 &
H42).
rewrite H41 in H.
inv H.
rewrite H42 in Heqo0 by assumption.
discriminate.
---
eauto with coqlib.
**
eauto.
--
constructor;
simpl;
intros.
++
destruct H.
**
inv H.
apply in_map_iff in H0.
destruct H0 as ((
v0',
n_v0) &
H0' &
H0).
simpl in H0'.
subst.
apply ZSortWithIndex.incl_merge in H0.
simpl in H0.
destruct H0 as [
H0|
H0].
---
inv H0.
exists u0.
split.
left;
reflexivity.
constructor.
---
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
w &
H3 &
H4).
exists w.
split; [
right;
assumption|].
apply black_reduced_reachable_bis_back;
assumption.
**
exploit BACK_SOURCE_GRAY.
right;
eassumption.
eassumption.
intros (
w &
H1 &
H2).
exists w.
split; [
right;
assumption|].
apply black_reduced_reachable_bis_back;
assumption.
++
exploit BACK_SOURCE;
eauto.
intros (
w &
H1 &
H2).
exists w.
split; [
right;
assumption|].
apply black_reduced_reachable_bis_back;
assumption.
++
eauto.
++
destruct H.
---
inv H.
exploit BACK_UPWARDS_GRAY;
eauto.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
intros.
apply in_map_iff in H5.
destruct H5 as ((
w',
n_w) &
H5' &
H5).
simpl in H5'.
subst.
exploit H2;
eauto.
intros [
contra|
contra]; [|
contradiction].
subst.
apply H3.
left;
reflexivity.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros H6.
apply in_map_iff in H6.
destruct H6 as ((
w',
n_w') &
H6' &
H6).
simpl in H6'.
subst.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
reflexivity.
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H61 &
_ &
H62).
rewrite H61 in H1.
inv H1.
eapply reachable_succ.
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5.
rewrite HH.
left;
reflexivity.
eassumption.
apply H62.
left;
reflexivity.
}
assert (
reachable ginit root x2)
as Hd.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
Hd' &
_).
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
right;
eassumption.
---
exploit BACK_UPWARDS_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split; [
assumption|].
eauto.
++
eauto.
++
destruct H.
**
inv H.
exploit CLASSIFY_BACK_GRAY.
left;
reflexivity.
intros (
l' &
H1 &
H2).
exists l'.
split.
assumption.
intros.
destruct (
peq v0 v).
---
subst.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
reflexivity.
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
eapply reachable_succ;
try eassumption.
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5.
rewrite HH.
left;
reflexivity.
}
assert (
reachable ginit root x2)
as Hd.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
Hd' &
_).
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
left;
reflexivity.
---
destruct H3; [
congruence|].
exploit H2;
eauto.
intros [
contra|
contra];
congruence.
intros.
apply in_map_iff in H4.
destruct H4 as ((
v0',
n_v0) &
H4' &
H4).
simpl in H4'.
subst.
apply in_map_iff.
eexists (
_,
_).
split; [
reflexivity|].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
reflexivity.
}
assert (
N =
dom_pre x2)
as Hb.
{
destruct INVARIANT9 as [
INVARIANT9 _ _ _].
exploit INVARIANT9;
eauto.
rewrite HH.
left;
reflexivity.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
}
assert (
reachable ginit root x1)
as Hc.
{
simpl in Hx1.
destruct Hx1 as [
Hx1|[]].
inv Hx1.
destruct INVARIANT as [
_ _ _ _ _ _ _ _ _ INVARIANT _].
exploit INVARIANT.
rewrite HH.
left;
reflexivity.
intros (
_ &
l'' &
H61 &
_ &
H62).
rewrite H61 in H1.
inv H1.
eapply reachable_succ.
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5.
rewrite HH.
left;
reflexivity.
eassumption.
apply H62.
left;
reflexivity.
}
assert (
reachable ginit root x2)
as Hd.
{
exploit BACK_SOURCE_GRAY;
eauto.
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros (
x' &
Hd' &
_).
pose proof INVARIANT5 as [
_ _ _ _ _ _ _ _ BACK_IN_GRAPH].
destruct (
BACK_IN_GRAPH _ _ Hd')
as (
succs &
H81 &
H82).
eapply reachable_succ with (
x:=
x');
try eassumption.
pose proof INVARIANT5
as [
_ _ _ _ _ _ BACK_SOURCE_GRAY_OR_BLACK].
apply BACK_SOURCE_GRAY_OR_BLACK in Hd'.
destruct Hd'
as [(? & ? & ? &
Hd')|
Hd'].
destruct INVARIANT5 as [
_ INVARIANT5 _ _ _ _ _].
eapply INVARIANT5;
eassumption.
destruct INVARIANT5 as [
_ _ INVARIANT5 _ _ _ _].
eapply INVARIANT5;
eassumption.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
right;
eassumption.
**
exploit CLASSIFY_BACK_GRAY.
right;
eassumption.
intros (
l' &
H1 &
H2).
exists l'.
split.
assumption.
intros.
destruct H4.
---
inv H4.
destruct INVARIANT4 as [
INVARIANT4 _ _ _ _ _ _ _ _].
rewrite HH in INVARIANT4.
inv INVARIANT4.
contradiction H6.
apply InA_alt.
eexists (
_,
_,
_,
_).
split.
reflexivity.
eassumption.
---
eauto.
++
destruct H.
**
inv H.
destruct INVARIANT4 as [
_ INVARIANT4 _ _ _ _ _ _ _].
exploit INVARIANT4.
rewrite HH.
left;
reflexivity.
congruence.
**
eauto.
Qed.
End DOM_PRE_HYPS.
End DOM_PRE.
Lemma initial_state_spec6:
invariant6 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
destruct H;
inv H.
contradiction H0.
+
rewrite PTree.gempty in H.
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros.
contradiction.
+
rewrite PTree.gempty in H3.
discriminate.
+
destruct H;
inv H.
exists l.
split; [
assumption|].
intros;
contradiction.
+
contradiction.
-
constructor;
simpl;
intros.
+
contradiction.
+
rewrite PTree.gempty in H.
discriminate.
+
rewrite PTree.gempty in H.
discriminate.
+
contradiction.
+
rewrite PTree.gempty in H3.
discriminate.
+
contradiction.
+
contradiction.
Qed.
Inductive invariant7 (
s:
state) :
Prop :=
Invariant7
(
BACK_NUMBERS_DECREASE_GRAY :
forall u n l post v m1 m2,
In (
u,
n,
l,
post)
s.(
wrk) ->
s.(
r) !
v =
Some (
m1,
m2) ->
In (
v,
u)
s.(
back) ->
n <
m1)
(
BACK_NUMBERS_DECREASE :
forall u v n1 n2 m1 m2,
In (
u,
v)
s.(
back) ->
s.(
r) !
u =
Some (
n1,
n2) ->
s.(
r) !
v =
Some (
m1,
m2) ->
is_included (
n1,
n2) (
m1,
m2)).
Inductive postcondition7
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition7
(
BACK_NUMBERS_DECREASE :
let '(
r,
c,
t,
back) :=
acc in
forall u v n1 n2 m1 m2,
In (
u,
v)
back ->
r !
u =
Some (
n1,
n2) ->
r !
v =
Some (
m1,
m2) ->
is_included (
n1,
n2) (
m1,
m2)).
Lemma transition_spec7:
forall dom_pre s (
INVARIANT :
invariant s) (
INVARIANT2 :
invariant2 s)
(
INVARIANT3 :
invariant3 s) (
INVARIANT4 :
invariant4 s) (
INVARIANT5 :
invariant5 s),
invariant7 s ->
match transition dom_pre s with inr s' =>
invariant7 s' |
inl m =>
postcondition7 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
rewrite PTree.gsspec in H0.
destruct (
peq v u).
--
subst v.
inv H0.
destruct INVARIANT2 as [
_ _ _ _ INVARIANT2 _ _ _].
apply Sorted_StronglySorted in INVARIANT2.
rewrite HH in INVARIANT2.
inv INVARIANT2.
rewrite Forall_forall in H4.
specialize (
H4 _ H).
apply H4.
intros (((
_,
n1),
_),
_) (((
_,
n2),
_),
_) (((
_,
n3),
_),
_).
eauto using Pos.lt_trans.
--
eauto with coqlib.
*
rewrite PTree.gsspec in H0.
destruct (
peq u0 u).
--
subst u0.
inv H0.
rewrite PTree.gsspec in H1.
destruct (
peq v u).
++
inv H1.
split;
reflexivity.
++
destruct INVARIANT3 as [
_ _ _ INVARIANT3].
exploit INVARIANT3.
rewrite HH.
left;
reflexivity.
intros (
l' &
H2 &
H3).
destruct INVARIANT5 as [
_ _ _ _ _ _ _ _ INVARIANT5].
destruct (
INVARIANT5 _ _ H)
as (
succs &
H41 &
H42).
rewrite H2 in H41.
inv H41.
exploit H3;
try eassumption.
unfold pre in *.
congruence.
--
rewrite PTree.gsspec in H1.
destruct (
peq v u).
++
subst v.
inv H1.
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in H0 as H1.
destruct H1 as (
_ &
H1).
exploit BACK_NUMBERS_DECREASE_GRAY.
left;
reflexivity.
eassumption.
eassumption.
xomega.
++
eapply BACK_NUMBERS_DECREASE;
eassumption.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
destruct H as [
H|[
H|
H]].
++
inv H.
destruct INVARIANT2 as [
_ _ _ _ _ _ _ INVARIANT2].
apply INVARIANT2 in H1 as (
_ &
H1).
congruence.
++
inv H.
eauto with coqlib.
++
eauto with coqlib.
--
eapply BACK_NUMBERS_DECREASE;
eassumption.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
destruct H as [
H|
H].
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eapply BACK_NUMBERS_DECREASE;
eassumption.
++
constructor;
simpl;
intros.
**
destruct H as [
H|
H].
---
inv H.
eauto with coqlib.
---
eauto with coqlib.
**
eapply BACK_NUMBERS_DECREASE;
eassumption.
--
constructor;
simpl;
intros.
++
destruct H as [
H|
H].
**
inv H.
destruct H1.
---
inv H.
congruence.
---
eauto with coqlib.
**
destruct H1.
---
inv H1.
destruct INVARIANT4 as [
_ INVARIANT4 _ _ _ _ _ _ _].
exploit INVARIANT4.
rewrite HH.
left;
reflexivity.
congruence.
---
eauto with coqlib.
++
destruct H.
**
inv H.
congruence.
**
eapply BACK_NUMBERS_DECREASE;
eassumption.
Qed.
Lemma initial_state_spec7:
invariant7 (
init_state ginit root).
Proof.
unfold init_state.
destruct (
ginit!
root)
as [
succs|]
eqn:?.
-
constructor;
simpl;
intros.
+
contradiction.
+
contradiction.
-
constructor;
simpl;
intros.
+
contradiction.
+
contradiction.
Qed.
Inductive invariant8 (
s:
state) :
Prop :=
Invariant8
(
CROSS_NUMBERS_DECREASE_BLACK :
forall u set v,
s.(
c) !
u =
Some set ->
set !
v =
Some tt ->
v <>
u ->
exists n1 n2 m1 m2,
s.(
r) !
u =
Some (
n1,
n2) /\
s.(
r) !
v =
Some (
m1,
m2) /\
m2 <
n1).
Inductive postcondition8
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition8
(
CROSS_NUMBERS_DECREASE :
let '(
r,
c,
t,
back) :=
acc in
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
v <>
u ->
exists n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) /\
r !
v =
Some (
m1,
m2) /\
m2 <
n1).
Lemma transition_spec8:
forall dom_pre s (
INVARIANT :
invariant s) (
INVARIANT2 :
invariant2 s)
(
INVARIANT4 :
invariant4 s) (
INVARIANT5 :
invariant5 s),
invariant8 s ->
match transition dom_pre s with inr s' =>
invariant8 s' |
inl m =>
postcondition8 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
eauto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
--
inv H.
rewrite PTree.gso in H0 by assumption.
rewrite PTree.gfilter in H0.
destruct (
s_c !
v)
as [[]|]
eqn:
Heqv; [|
discriminate].
unfold is_directly_included in H0.
rewrite PTree.gss in H0.
rewrite PTree.gsspec in H0.
destruct (
peq v u).
++
exfalso.
subst v.
destruct INVARIANT4
as [
_ WRK_NOT_BLACK _ _ _ CROSS_TARGETS_BLACK_GRAY _ _ _].
exploit WRK_NOT_BLACK.
rewrite HH.
left;
reflexivity.
intros.
eapply CROSS_TARGETS_BLACK_GRAY;
eauto.
rewrite HH.
left;
reflexivity.
++
unfold pre in *.
destruct (
s.(
r) !
v)
as [(
n1,
n2)|]
eqn:
Heqrv.
**
destruct (
test_is_included _ _)
eqn:
Htest; [
discriminate|].
rewrite PTree.gss.
rewrite PTree.gso by assumption.
eexists _,
_,
_,
_.
split; [
reflexivity|].
split; [
eassumption|].
unfold test_is_included in Htest.
apply not_true_iff_false in Htest.
rewrite andb_true_iff in Htest.
rewrite 2!
Pos.leb_le in Htest.
destruct INVARIANT2 as [
_ _ _ _ _ INVARIANT2 _ _].
exploit INVARIANT2.
rewrite HH.
left;
reflexivity.
eassumption.
destruct INVARIANT as [
_ _ _ INVARIANT _ _ _ _ _ _ _].
apply INVARIANT in Heqrv.
xomega.
**
destruct INVARIANT4 as [
_ _ _ _ _ INVARIANT4 _ _ _].
exploit INVARIANT4;
eauto.
rewrite HH.
left;
reflexivity.
contradiction.
--
rewrite PTree.gso by assumption.
rewrite PTree.gso;
eauto.
intros contra;
subst v.
destruct INVARIANT4 as [
_ WRK_NOT_BLACK _ _ _ _ CROSS_TARGETS_BLACK_BLACK _ _].
exploit WRK_NOT_BLACK.
rewrite HH.
left;
reflexivity.
intros.
eapply CROSS_TARGETS_BLACK_BLACK;
eauto.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
eauto.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
eauto.
++
constructor;
simpl;
intros.
eauto.
--
constructor;
simpl;
intros.
eauto.
Qed.
Lemma initial_state_spec8:
invariant8 (
init_state ginit root).
Proof.
Inductive invariant10 (
s:
state) :
Prop :=
Invariant10
(
ROOT_LAST_WRK :
exists l post,
last s.(
wrk) (
root, 1,
l,
post) = (
root, 1,
l,
post))
(
ROOT_REACHABLE :
s.(
wrk) =
nil ->
forall u,
s.(
r) !
u <>
None ->
reduced_reachable ginit s.(
back)
root u).
Inductive postcondition10
(
acc :
PTree.t (
positive *
positive)
*
PTree.t (
PTree.t unit)
*
PTree.t (
list (
node *
Z))
*
list (
node *
node))
:
Prop :=
Postcondition10
(
ROOT_REACHABLE :
let '(
r,
c,
t,
back) :=
acc in
forall u,
r !
u <>
None ->
reduced_reachable ginit back root u).
Lemma transition_spec10:
forall dom_pre s (
INVARIANT2 :
invariant2 s),
invariant10 s ->
match transition dom_pre s with inr s' =>
invariant10 s' |
inl m =>
postcondition10 m end.
Proof.
intros.
inv H.
unfold transition.
destruct (
wrk s)
as [ | [[[
u n]
succs] [
s_c s_t]]
l]
eqn:
HH.
-
constructor;
intros.
auto.
-
destruct succs as [ |
v succs ].
+
constructor;
simpl;
intros.
*
destruct ROOT_LAST_WRK as (
l' &
post' &
H).
exists l',
post'.
destruct l.
--
reflexivity.
--
assumption.
*
subst l.
destruct ROOT_LAST_WRK as (
l' &
post' &
ROOT_LAST_WRK).
simpl in ROOT_LAST_WRK.
inv ROOT_LAST_WRK.
rewrite PTree.gsspec in H0.
destruct (
peq u0 root).
--
subst u0.
constructor.
--
unfold pre in *.
destruct (
s.(
r) !
u0)
as [(
n1,
n2)|]
eqn:
Hr; [|
contradiction].
destruct INVARIANT2 as [
_ _ INVARIANT2 _ _ _ _ _].
exploit INVARIANT2;
try eassumption.
xomega.
intros.
apply black_reduced_reachable_bis_is_reduced_reachable in H.
assumption.
+
destruct ((
gr s)!
v)
as [
succs_v | ]
eqn:?.
*
constructor;
simpl;
intros.
--
assumption.
--
discriminate.
*
destruct (
s.(
r) !
v)
as [ (
n1,
n2) |]
eqn:?.
--
destruct (
Pos.ltb_spec0 n1 n).
++
constructor;
simpl;
intros.
**
destruct ROOT_LAST_WRK as (
l' &
post' &
H).
destruct l.
---
simpl in H.
inv H.
eexists _,
_.
reflexivity.
---
exists l',
post'.
assumption.
**
discriminate.
++
constructor;
simpl;
intros.
**
destruct ROOT_LAST_WRK as (
l' &
post' &
H).
destruct l.
---
simpl in H.
inv H.
eexists _,
_.
reflexivity.
---
exists l',
post'.
assumption.
**
discriminate.
--
constructor;
simpl;
intros.
++
destruct ROOT_LAST_WRK as (
l' &
post' &
H).
destruct l.
**
simpl in H.
inv H.
eexists _,
_.
reflexivity.
**
exists l',
post'.
assumption.
++
discriminate.
Qed.
Lemma initial_state_spec10:
invariant10 (
init_state ginit root).
Proof.
End POSTORDER.
Theorem precompute_r_t_up_correct_1:
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall x1 x2 m n1 n2,
r!
x1 =
Some (
m,
n1) ->
r!
x2 =
Some (
m,
n2) ->
x1 =
x2)
/\ (
forall x,
reachable g root x ->
g!
x <>
None ->
r!
x <>
None)
/\ (
forall x n1 n2,
r !
x =
Some (
n1,
n2) ->
Ple n1 n2).
Proof.
Lemma precompute_r_t_up_correct_2 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall x1 x2 n1 n2 m1 m2,
r !
x1 =
Some (
n1,
n2) ->
r!
x2 =
Some (
m1,
m2) ->
is_included (
m1,
m2) (
n1,
n2) ->
reduced_reachable g back x1 x2)
/\ (
forall u v n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) ->
r !
v =
Some (
m1,
m2) ->
m2 <
n1 \/
n2 <
m1
\/
is_included (
m1,
m2) (
n1,
n2)
\/
is_included (
n1,
n2) (
m1,
m2)) .
Proof.
Lemma precompute_r_t_up_correct_3 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
reduced_reachable g back u v.
Proof.
Lemma precompute_r_t_up_correct_4 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall u v,
reachable g root u ->
reduced_reachable g back u v ->
g !
v <>
None ->
cross_included r c u v)
/\ (
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
r !
v <>
None)
/\ (
forall u,
r !
u <>
None ->
exists set,
c !
u =
Some set /\
set !
u =
Some tt).
Proof.
Lemma precompute_r_t_up_correct_5 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall u,
r !
u <>
None ->
reachable g root u /\
g !
u <>
None)
/\ (
forall u,
c !
u <>
None ->
r !
u <>
None)
/\ (
forall u succs v,
g !
u =
Some succs ->
In v succs ->
g !
v =
None ->
r !
u <>
None ->
In (
u,
v)
back)
/\ (
forall u v,
In (
u,
v)
back ->
r !
u <>
None)
/\ (
forall u,
t !
u <>
None <->
r !
u <>
None)
/\ (
forall u v,
In (
u,
v)
back ->
exists succs,
g !
u =
Some succs /\
In v succs).
Proof.
Lemma precompute_r_t_up_correct_6 :
forall g root dom_pre
(
dom_pre_inj :
forall u v,
reachable g root u ->
reachable g root v ->
dom_pre u =
dom_pre v ->
u =
v),
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall u v,
(
reachable g root u /\
g !
u <>
None /\
is_in_t_up g back u v)
<->
exists set,
t !
u =
Some set /\
In v (
map fst set)).
Proof.
Lemma precompute_r_t_up_correct_7 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
forall u v,
In (
u,
v)
back ->
g !
v <>
None ->
directly_included r v u.
Proof.
Lemma precompute_r_t_up_correct_8 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
forall u set v,
c !
u =
Some set ->
set !
v =
Some tt ->
v <>
u ->
exists n1 n2 m1 m2,
r !
u =
Some (
n1,
n2) /\
r !
v =
Some (
m1,
m2) /\
m2 <
n1.
Proof.
Lemma precompute_r_t_up_correct_9 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
(
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
/\ (
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set).
Proof.
Lemma precompute_r_t_up_correct_10 :
forall g root dom_pre,
let '(
r,
c,
t,
back) :=
precompute_r_t_up g root dom_pre in
forall u,
r !
u <>
None ->
reduced_reachable g back root u.
Proof.