Module SSAfastliveprecomputeTTproof
Require Import Relation_Operators.
Require Import Sorted.
Import List.ListNotations.
Require Import Coqlib.
Require Import Maps.
Require Import Utils.
Require Import SSAfastliveutils.
Require Import SSAfastliveprecomputeRT.
Require Import SSAfastliveprecomputeRTthm.
Require Import SSAfastliveprecomputeTT.
Local Open Scope positive_scope.
Local Opaque ZSortWithIndex.merge.
Module Import Definitions.
Definition is_in_t g back :=
clos_refl_trans _ (
is_in_t_up g back).
Definition t_linked t (
u v :
node) :=
exists set,
t !
u =
Some set /\
In v set.
Definition t_linked'
t (
u v :
node) :=
exists (
set :
list (
node *
Z)),
t !
u =
Some set /\
In v (
List.map fst set).
End Definitions.
Lemma precompute_t_from_t_up_1_not_back :
forall dom_pre pre t back u
(
u_not_target : ~
In u (
List.map snd back)),
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u =
t !
u.
Proof.
Lemma equation1 :
forall g back u v,
is_in_t g back u v <->
u =
v \/
exists w,
is_in_t_up g back u w /\
is_in_t g back w v.
Proof.
Lemma precompute_t_from_t_up_1_back_1 :
forall dom_pre pre t back u v,
t_linked' (
precompute_t_from_t_up_1 dom_pre pre t back)
u v ->
clos_refl_trans _ (
t_linked'
t)
u v.
Proof.
intros.
revert u v H.
unfold precompute_t_from_t_up_1.
apply fold_invariant;
intros.
-
apply rt_step.
assumption.
-
unfold t_linked'
in H1.
rewrite PTree.gsspec in H1.
destruct (
peq u x); [|
eauto].
destruct H1 as (
set' &
H11 &
H12).
inv H11.
apply in_map_iff in H12.
destruct H12 as ((
v',
n_v) &
H12' &
H12).
simpl in H12'.
subst.
destruct (
t0 !
x)
as [
set|]
eqn:
Ht0.
+
apply ZSortWithIndex.incl_merge in H12.
simpl in H12.
destruct H12 as [
H12|
H12].
*
inv H12.
apply rt_refl.
*
revert H12.
apply fold_invariant.
--
intros [].
--
intros (
w,
n_w)
set'.
intros.
destruct (
t0 !
w)
as [
set''|]
eqn:
Ht0'.
++
apply ZSortWithIndex.incl_merge in H12.
rewrite in_app_iff in H12.
destruct H12 as [
H12|
H12].
**
eapply rt_trans.
---
apply H0.
exists set.
split; [
assumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
---
apply H0.
exists set''.
split; [
assumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
**
apply H2.
assumption.
++
auto.
+
destruct H12 as [
H12|[]].
inv H12.
apply rt_refl.
Qed.
Module Precompute_t_from_t_up_back_targets.
Module Import Postorder.
Module Import State.
Record state :
Type :=
mkstate {
l:
list node;
(* current list, without already-visited nodes *)
t :
PTree.t (
list (
node *
Z))
(* current result *)
}.
End State.
Definition init_state t back :=
{|
l :=
back;
t :=
t |}.
Definition transition dom_pre (
s:
state) :
PTree.t (
list (
node *
Z)) +
state :=
match s.(
l)
with
|
nil =>
inl _ s.(
t)
|
u ::
m =>
let set :=
match s.(
t) !
u with
|
None => [(
u,
dom_pre u)]
|
Some set =>
let set :=
List.fold_left (
fun acc '((
u,
_) :
node *
Z) =>
match s.(
t) !
u with
|
None =>
acc
|
Some s =>
ZSortWithIndex.merge s acc
end)
set []
in
ZSortWithIndex.merge [(
u,
dom_pre u)]
set
end
in
let t' :=
PTree.set u set s.(
t)
in
inr _ {|
l :=
m;
t :=
t' |}
end.
Definition f (
dom_pre :
node ->
Z)
:
PTree.t (
list (
node *
Z)) ->
node ->
PTree.t (
list (
node *
Z))
:= (
fun t u =>
let s :=
match t !
u with
|
None => [(
u,
dom_pre u)]
|
Some s =>
let s :=
List.fold_left (
fun acc '(
u,
_) =>
match t !
u with
|
None =>
acc
|
Some s =>
ZSortWithIndex.merge s acc
end)
s []
in
ZSortWithIndex.merge [(
u,
dom_pre u)]
s
end
in
PTree.set u s t
).
Section POSTORDER.
Variable dom_pre :
node ->
Z.
Variable pre :
node ->
positive.
Variable tinit :
PTree.t (
list (
node *
Z)).
Variable back_targets:
list node.
Hypothesis dom_pre_inj :
forall u v,
In u back_targets ->
In v back_targets ->
dom_pre u =
dom_pre v ->
u =
v.
Hypothesis t_pre :
forall u v,
t_linked'
tinit u v ->
pre v <
pre u.
Hypothesis t_in_back_targets :
forall u v,
t_linked'
tinit u v ->
In v back_targets.
Inductive invariant (
s:
state) :
Prop :=
Invariant
(
SORTED :
Sorted (
fun u v =>
pre u <
pre v)
s.(
l))
(
SORTED_DONE :
forall u v,
In u back_targets -> ~
In u s.(
l) ->
In v s.(
l) ->
pre u <
pre v)
(
INCL :
incl s.(
l)
back_targets)
(
T_TODO :
forall u,
In u s.(
l) ->
s.(
t) !
u =
tinit !
u)
(
T_IN_BACK :
forall u v,
t_linked'
s.(
t)
u v ->
In v back_targets)
(
T_REFL :
forall u,
In u back_targets -> ~
In u s.(
l) ->
t_linked'
s.(
t)
u u)
(
T_TRANS :
forall u v w,
In u back_targets -> ~
In u s.(
l) ->
t_linked'
tinit u v ->
t_linked'
s.(
t)
v w ->
t_linked'
s.(
t)
u w)
(
T_DOM_PRE :
forall u set,
s.(
t) !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
T_SORTED :
forall u set,
s.(
t) !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
FOLD :
fold_left (
f dom_pre)
s.(
l)
s.(
t) =
fold_left (
f dom_pre)
back_targets tinit).
Inductive postcondition (
t:
PTree.t (
list (
node *
Z))) :
Prop :=
Postcondition
(
T_REFL :
forall u,
In u back_targets ->
t_linked'
t u u)
(
T_TRANS :
forall u v w,
In u back_targets ->
t_linked'
tinit u v ->
t_linked'
t v w ->
t_linked'
t u w)
(
T_DOM_PRE :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
T_SORTED :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
FOLD :
t =
fold_left (
f dom_pre)
back_targets tinit).
Lemma transition_spec:
forall 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 (
l s)
as [ |
u m].
-
constructor;
simpl;
intros.
+
auto.
+
eauto.
+
eauto.
+
eauto.
+
assumption.
-
constructor;
simpl;
intros.
+
inv SORTED;
assumption.
+
destruct (
peq u0 u).
*
subst.
apply Sorted_StronglySorted in SORTED.
--
inv SORTED.
rewrite Forall_forall in H5.
apply H5.
assumption.
--
intros x1 x2 x3 H2 H3.
rewrite H2.
assumption.
*
eapply SORTED_DONE;
try eassumption.
--
intros [
contra|
contra];
congruence.
--
right;
assumption.
+
apply incl_cons_inv in INCL.
assumption.
+
rewrite PTree.gso.
eauto.
intros contra.
subst u0.
apply Sorted_StronglySorted in SORTED.
--
inv SORTED.
rewrite Forall_forall in H3.
specialize (
H3 _ H).
xomega.
--
intros x1 x2 x3 H2 H3.
rewrite H2.
assumption.
+
unfold t_linked'
in H.
rewrite PTree.gsspec in H.
destruct (
peq u0 u).
*
subst u0.
destruct H as (
set &
H1 &
H2).
inv H1.
destruct (
s.(
t) !
u)
as [
set|]
eqn:
Ht.
--
apply in_map_iff in H2.
destruct H2 as ((
v',
n_v) &
H2' &
H2).
simpl in H2'.
subst.
apply ZSortWithIndex.incl_merge in H2.
simpl in H2.
destruct H2 as [
H2|
H2].
++
inv H2.
apply INCL.
left;
reflexivity.
++
revert H2.
apply fold_invariant.
**
intros [].
**
intros (
x,
n_x)
set'.
intros.
destruct (
s.(
t) !
x)
as [
set''|]
eqn:
Ht'.
---
apply ZSortWithIndex.incl_merge in H2.
rewrite in_app_iff in H2.
destruct H2 as [
H2|
H2].
+++
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
+++
auto.
---
auto.
--
simpl in H2.
destruct H2 as [
H2|[]].
subst.
apply INCL.
left;
reflexivity.
*
eauto.
+
unfold t_linked'.
rewrite PTree.gsspec.
destruct (
peq u0 u).
*
subst u0.
eexists;
split; [
reflexivity|].
destruct (
s.(
t) !
u)
as [
set|]
eqn:
Ht.
--
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.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set''.
intros.
destruct (
s.(
t) !
x2')
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
*
eauto.
+
eauto.
}
assert (
In x1 back_targets)
as Hc.
{
destruct Hx1 as [
Hx1|[]].
inv Hx1.
eauto.
}
assert (
In x2 back_targets)
as Hd.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set'.
intros.
destruct (
s.(
t) !
x2')
as [
set''|]
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
*
auto.
+
auto.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
left;
reflexivity.
--
simpl.
left;
reflexivity.
*
apply T_REFL;
try assumption.
intros [
contra|
contra];
congruence.
+
unfold t_linked'
in H2.
rewrite PTree.gso in H2.
*
unfold t_linked'.
rewrite PTree.gsspec.
destruct (
peq u0 u).
--
subst u0.
eexists;
split; [
reflexivity|].
destruct H1 as (
set &
H11 &
H12).
rewrite <-
T_TODO in H11 by (
left;
reflexivity).
rewrite H11.
apply in_map_iff in H12.
destruct H12 as ((
v',
n_v) &
H12' &
H12).
simpl in H12'.
subst.
destruct H2 as (
set' &
H21 &
H22).
apply in_map_iff in H22.
destruct H22 as ((
w',
n_w) &
H22' &
H22).
simpl in H22'.
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.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set''.
intros.
destruct (
s.(
t) !
x2')
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
*
eauto.
+
eauto.
}
assert (
In x1 back_targets)
as Hc.
{
destruct Hx1 as [
Hx1|[]].
inv Hx1.
eauto.
}
assert (
In x2 back_targets)
as Hd.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set''.
intros.
destruct (
s.(
t) !
x2')
as [
set'''|]
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
*
auto.
+
auto.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
right.
apply fold_becomes_true_growing_with_invariant
with
(
P0 :=
fun l =>
forall x n_x,
In (
x,
n_x)
l ->
exists x'
set,
s.(
t) !
x' =
Some set /\
In (
x,
n_x)
set).
++
intros ? ? [].
++
intros (
x,
n_x)
set''.
intros.
destruct (
s.(
t) !
x)
as [
set'''|]
eqn:
Ht.
**
apply ZSortWithIndex.incl_merge in H3.
rewrite in_app_iff in H3.
destruct H3 as [
H3|
H3].
---
exists x,
set'''.
split;
assumption.
---
auto.
**
auto.
++
apply Exists_exists.
eexists (
_,
_);
split; [
eassumption|].
intros set''.
intros.
rewrite H21.
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
exploit H1;
try eassumption.
intros (
x2' &
set''' &
Hx2' &
Hx2'').
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2'').
}
assert (
In x1 back_targets)
as Hc.
{
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
assert (
In x2 back_targets)
as Hd.
{
exploit H1;
try eassumption.
intros (
x2' &
set''' &
Hx2' &
Hx2'').
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
left;
eassumption.
++
intros (
x,
n_x)
set''.
intros.
destruct (
s.(
t) !
x)
as [
set'''|]
eqn:
Ht.
**
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
exploit H2;
try eassumption.
intros (
x2' &
set'''' &
Hx2' &
Hx2'').
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2'').
}
assert (
In x1 back_targets)
as Hc.
{
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
assert (
In x2 back_targets)
as Hd.
{
exploit H2;
try eassumption.
intros (
x2' &
set'''' &
Hx2' &
Hx2'').
eapply T_IN_BACK.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
assumption.
**
assumption.
--
eapply T_TRANS;
eauto.
intros [
contra|
contra];
congruence.
*
intros contra.
subst.
apply t_pre in H1.
exploit SORTED_DONE;
eauto.
intros [
contra|
contra]; [
subst;
xomega|
contradiction].
xomega.
+
rewrite PTree.gsspec in H.
destruct (
peq u0 u); [|
eauto].
subst u0.
inv H.
destruct (
s.(
t) !
u)
as [
set|]
eqn:
Ht.
*
rewrite Forall_forall.
intros (
x,
n_x).
intros.
apply ZSortWithIndex.incl_merge in H.
simpl in H.
destruct H as [
H|
H].
--
inv H.
reflexivity.
--
revert H.
apply fold_invariant.
++
intros [].
++
intros (
x',
n_x')
set'.
intros.
destruct (
s.(
t) !
x')
as [
set''|]
eqn:
Heqt.
**
apply ZSortWithIndex.incl_merge in H1.
rewrite in_app_iff in H1.
destruct H1 as [
H1|
H1].
---
exploit T_DOM_PRE;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ H1).
---
auto.
**
auto.
*
constructor; [
reflexivity|
constructor].
+
rewrite PTree.gsspec in H.
destruct (
peq u0 u); [|
eauto].
subst u0.
inv H.
destruct (
s.(
t) !
u)
as [
set|]
eqn:
Ht.
*
apply Sorted_LocallySorted_iff.
apply ZSortWithIndex.Sorted_merge.
--
constructor.
--
apply fold_invariant.
++
constructor.
++
intros (
x,
n_x)
set'.
intros.
destruct (
s.(
t) !
x)
as [
set''|]
eqn:
Ht'.
**
apply ZSortWithIndex.Sorted_merge.
---
apply Sorted_LocallySorted_iff.
eauto.
---
assumption.
**
assumption.
*
constructor;
constructor.
+
rewrite <-
FOLD.
simpl.
f_equal.
Qed.
Hypothesis t_dom_pre :
forall u set,
tinit !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set.
Hypothesis t_sorted :
forall u set,
tinit !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set.
Hypothesis back_targets_sorted :
Sorted (
fun u v =>
pre u <
pre v)
back_targets.
Lemma initial_state_spec:
invariant (
init_state tinit back_targets).
Proof.
unfold init_state.
constructor;
simpl;
intros.
-
assumption.
-
contradiction.
-
apply incl_refl.
-
reflexivity.
-
eauto.
-
contradiction.
-
contradiction.
-
eauto.
-
eauto.
-
reflexivity.
Qed.
Termination criterion.
Definition lt_state (
s1 s2:
state) :
Prop :=
(
length s1.(
l) <
length s2.(
l))%
nat.
Lemma lt_state_wf:
well_founded lt_state.
Proof.
Lemma transition_decreases:
forall dom_tre s s',
transition dom_tre s =
inr _ s' ->
lt_state s'
s.
Proof.
unfold transition,
lt_state;
intros.
destruct (
l s)
as [ |
u m].
-
discriminate.
-
destruct (
s.(
t) !
u)
as [
set|].
+
inv H;
simpl.
apply le_n.
+
inv H;
simpl.
apply le_n.
Qed.
End POSTORDER.
Definition postorder dom_pre t back_targets :=
Iteration.WfIter.iterate _ _
(
transition dom_pre)
lt_state lt_state_wf (
transition_decreases dom_pre) (
init_state t back_targets).
End Postorder.
Lemma precompute_t_from_t_up_1_back_2 :
forall dom_pre pre t back
(
dom_pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
t_pre :
forall u v,
t_linked'
t u v ->
pre v <
pre u)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
pre u =
pre v ->
u =
v)
u (
u_target :
In u (
map snd back))
v,
clos_refl_trans _ (
t_linked'
t)
u v ->
t_linked' (
precompute_t_from_t_up_1 dom_pre pre t back)
u v.
Proof.
Lemma precompute_t_from_t_up_1_dom_pre :
forall dom_pre pre t back
(
dom_pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
t_pre :
forall u v,
t_linked'
t u v ->
pre v <
pre u)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
pre u =
pre v ->
u =
v)
u set,
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set.
Proof.
Lemma precompute_t_from_t_up_1_sorted :
forall dom_pre pre t back
(
dom_pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
t_pre :
forall u v,
t_linked'
t u v ->
pre v <
pre u)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
pre u =
pre v ->
u =
v)
u set,
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set.
Proof.
End Precompute_t_from_t_up_back_targets.
Lemma precompute_t_from_t_up_1_dom_pre :
forall dom_pre pre t back
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
u set,
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set.
Proof.
Lemma precompute_t_from_t_up_1_sorted :
forall dom_pre pre t back
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
u set,
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set.
Proof.
Theorem precompute_t_from_t_up_1_back :
forall dom_pre pre t back
(
dom_pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
(
t_pre :
forall u v,
t_linked'
t u v ->
pre v <
pre u)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
pre_inj :
forall u v,
In u (
map snd back) ->
In v (
map snd back) ->
pre u =
pre v ->
u =
v)
u (
u_target :
In u (
map snd back))
v,
t_linked' (
precompute_t_from_t_up_1 dom_pre pre t back)
u v
<->
clos_refl_trans _ (
t_linked'
t)
u v.
Proof.
Lemma precompute_t_from_t_up_1_black :
forall dom_pre pre t back u,
t !
u <>
None ->
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u <>
None.
Proof.
Lemma precompute_t_from_t_up_1_black_2 :
forall dom_pre pre t back u,
(
precompute_t_from_t_up_1 dom_pre pre t back) !
u <>
None ->
t !
u =
None ->
In u (
map snd back).
Proof.
Lemma precompute_t_from_t_up_2_correct_1 :
forall dom_pre t u v,
t_linked (
precompute_t_from_t_up_2 dom_pre t)
u v ->
clos_refl_trans _ (
t_linked'
t)
u v.
Proof.
Lemma precompute_t_from_t_up_2_refl :
forall dom_pre (
t :
PTree.t (
list (
node *
Z)))
(
dom_pre_inj :
forall u v,
t !
u <>
None \/ (
exists u',
t_linked'
t u'
u) ->
t !
v <>
None \/ (
exists v',
t_linked'
t v'
v) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
u,
t !
u <>
None ->
t_linked (
precompute_t_from_t_up_2 dom_pre t)
u u.
Proof.
intros.
unfold t_linked.
unfold precompute_t_from_t_up_2.
rewrite PTree.gmap.
unfold option_map.
destruct (
t !
u)
as [
set|]
eqn:
Ht; [|
contradiction].
eexists;
split; [
reflexivity|].
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.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set'.
intros.
destruct (
t !
x2')
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
*
eauto.
+
eauto.
}
assert (
t !
x1 <>
None)
as Hc.
{
destruct Hx1 as [
Hx1|[]].
inv Hx1.
congruence.
}
assert (
exists x2',
t_linked'
t x2'
x2)
as Hd.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set'.
intros.
destruct (
t !
x2')
as [
set''|]
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
exists x2'.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
*
auto.
+
auto.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
left;
reflexivity.
Qed.
Lemma precompute_t_from_t_up_2_trans :
forall dom_pre (
t :
PTree.t (
list (
node *
Z)))
back_targets
(
dom_pre_inj :
forall u v,
t !
u <>
None \/
In u back_targets ->
t !
v <>
None \/
In v back_targets ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v back_targets)
(
t_back_targets_refl :
forall u,
In u back_targets ->
t_linked'
t u u)
(
t_back_targets_trans :
forall u v w,
In u back_targets ->
t_linked'
t u v ->
t_linked'
t v w ->
t_linked'
t u w)
u v w,
t_linked'
t u v ->
t_linked (
precompute_t_from_t_up_2 dom_pre t)
v w ->
t_linked (
precompute_t_from_t_up_2 dom_pre t)
u w.
Proof.
intros.
unfold t_linked,
precompute_t_from_t_up_2 in H0 |- *.
rewrite PTree.gmap in H0 |- *.
unfold option_map in H0 |- *.
destruct H as (
set &
H1 &
H2).
apply in_map_iff in H2.
destruct H2 as ((
v',
n_v) &
H2' &
H2).
simpl in H2'.
subst.
rewrite H1.
eexists;
split; [
reflexivity|].
destruct H0 as (
set'' &
H01 &
H02).
destruct (
t !
v)
as [
set'|]
eqn:
Ht; [|
discriminate].
inv H01.
apply in_map_iff in H02.
destruct H02 as ((
w',
n_w) &
H02' &
H02).
simpl in H02'.
subst.
apply in_map_iff.
exists (
w,
n_w);
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.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set''.
intros.
destruct (
t !
x2')
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2).
*
eauto.
+
eauto.
}
assert (
t !
x1 <>
None)
as Hc.
{
destruct Hx1 as [
Hx1|[]].
inv Hx1.
congruence.
}
assert (
In x2 back_targets)
as Hd.
{
revert Hx2.
apply fold_invariant.
-
intros [].
-
intros (
x2',
n_x2')
set''.
intros.
destruct (
t !
x2')
as [
set'''|]
eqn:
Ht'.
+
apply ZSortWithIndex.incl_merge in Hx2.
rewrite in_app_iff in Hx2.
destruct Hx2 as [
Hx2|
Hx2].
*
apply (
t_in_back x2'
x2).
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
*
auto.
+
auto.
}
eapply dom_pre_inj;
eauto.
congruence.
}
simpl.
right.
apply fold_becomes_true_growing_with_invariant
with
(
P0 :=
fun l =>
forall x n_x,
In (
x,
n_x)
l ->
exists x'
set,
t !
x' =
Some set /\
In (
x,
n_x)
set).
-
intros ? ? [].
-
intros (
x,
n_x)
set''.
intros.
destruct (
t !
x)
as [
set'''|]
eqn:
Ht'.
**
apply ZSortWithIndex.incl_merge in H3.
rewrite in_app_iff in H3.
destruct H3 as [
H3|
H3].
---
exists x,
set'''.
split;
assumption.
---
auto.
**
auto.
-
apply Exists_exists.
eexists (
_,
_);
split; [
eassumption|].
intros set''.
intros.
rewrite Ht.
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
exploit H;
try eassumption.
intros (
x2' &
set''' &
Hx2' &
Hx2'').
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2'').
}
assert (
In x1 back_targets)
as Hc.
{
eapply t_in_back.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
assert (
In x2 back_targets)
as Hd.
{
exploit H;
try eassumption.
intros (
x2' &
set''' &
Hx2' &
Hx2'').
eapply t_in_back.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
left.
apply ZSortWithIndex.incl_merge in H02.
simpl in H02.
destruct H02 as [
H02|
H02].
+
inv H02.
exploit (
t_back_targets_refl w).
apply (
t_in_back u w).
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros.
destruct H0 as (
set''' &
H01 &
H02).
apply in_map_iff in H02.
destruct H02 as ((
w',
n_w') &
H02' &
H02).
simpl in H02'.
subst.
rewrite H01 in Ht.
inv Ht.
exploit t_dom_pre;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
rewrite <- (
HForall _ H02).
assumption.
+
revert H02.
apply fold_invariant.
*
intros [].
*
intros (
x,
n_x)
set'''.
intros.
destruct (
t !
x)
as [
set''''|]
eqn:
Ht'.
--
apply ZSortWithIndex.incl_merge in H02.
rewrite in_app_iff in H02.
destruct H02 as [
H02|
H02].
++
exploit (
t_back_targets_trans v x w).
apply (
t_in_back u v).
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
intros.
destruct H4 as (
set''''' &
H31 &
H32).
apply in_map_iff in H32.
destruct H32 as ((
w',
n_w') &
H32' &
H32).
simpl in H32'.
subst.
rewrite H31 in Ht.
inv Ht.
exploit t_dom_pre;
eauto.
intros HForall.
rewrite Forall_forall in HForall.
rewrite (
HForall _ H32)
in H32.
exploit t_dom_pre.
apply Ht'.
intros HForall'.
rewrite Forall_forall in HForall'.
rewrite (
HForall'
_ H02).
assumption.
++
auto.
--
auto.
-
intros (
x,
n_x)
set''.
intros.
destruct (
t !
x)
as [
set'''|]
eqn:
Ht'; [|
assumption].
apply ZSortWithIndex.incl_merge_2_inj.
{
intros x1 x2 N Hx1 Hx2.
assert (
N =
dom_pre x1)
as Ha.
{
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx1).
}
assert (
N =
dom_pre x2)
as Hb.
{
exploit H0;
try eassumption.
intros (
x2' &
set'''' &
Hx2' &
Hx2'').
exploit t_dom_pre;
try eassumption.
intros HForall.
rewrite Forall_forall in HForall.
apply (
HForall _ Hx2'').
}
assert (
In x1 back_targets)
as Hc.
{
eapply t_in_back.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
assert (
In x2 back_targets)
as Hd.
{
exploit H0;
try eassumption.
intros (
x2' &
set'''' &
Hx2' &
Hx2'').
eapply t_in_back.
eexists;
split; [
eassumption|].
apply in_map_iff.
eexists (
_,
_);
split; [
reflexivity|
eassumption].
}
eapply dom_pre_inj;
eauto.
congruence.
}
rewrite in_app_iff.
right;
assumption.
Qed.
Lemma precompute_t_from_t_up_2_correct_2 :
forall dom_pre (
t :
PTree.t (
list (
node *
Z))) (
back :
list (
node *
node))
(
dom_pre_inj :
forall u v,
t !
u <>
None \/
In u (
map snd back) ->
t !
v <>
None \/
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
t_back_targets_refl :
forall u,
In u (
map snd back) ->
t_linked'
t u u)
(
t_back_targets_trans :
forall u v w,
In u (
map snd back) ->
t_linked'
t u v ->
t_linked'
t v w ->
t_linked'
t u w)
u (
u_in_t :
t !
u <>
None)
v,
clos_refl_trans _ (
t_linked'
t)
u v ->
t_linked (
precompute_t_from_t_up_2 dom_pre t)
u v.
Proof.
Theorem precompute_t_from_t_up_2_correct :
forall dom_pre (
t :
PTree.t (
list (
node *
Z))) (
back :
list (
node *
node))
(
dom_pre_inj :
forall u v,
t !
u <>
None \/
In u (
map snd back) ->
t !
v <>
None \/
In v (
map snd back) ->
dom_pre u =
dom_pre v ->
u =
v)
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_in_back :
forall u v,
t_linked'
t u v ->
In v (
map snd back))
(
t_back_targets_refl :
forall u,
In u (
map snd back) ->
t_linked'
t u u)
(
t_back_targets_trans :
forall u v w,
In u (
map snd back) ->
t_linked'
t u v ->
t_linked'
t v w ->
t_linked'
t u w)
u (
u_in_t :
t !
u <>
None)
v,
t_linked (
precompute_t_from_t_up_2 dom_pre t)
u v <->
clos_refl_trans _ (
t_linked'
t)
u v.
Proof.
Lemma precompute_t_from_t_up_2_black :
forall dom_pre t u,
(
precompute_t_from_t_up_2 dom_pre t) !
u <>
None
<->
t !
u <>
None.
Proof.
Lemma precompute_t_from_t_up_2_sorted :
forall dom_pre (
t :
PTree.t (
list (
node *
Z)))
(
t_dom_pre :
forall u set,
t !
u =
Some set ->
Forall (
fun '(
u,
n) =>
n =
dom_pre u)
set)
(
t_sorted :
forall u set,
t !
u =
Some set ->
Sorted (
fun '(
_,
n1) '(
_,
n2) =>
n1 <
n2)%
Z set)
u set,
(
precompute_t_from_t_up_2 dom_pre t) !
u =
Some set ->
Sorted (
fun u v =>
dom_pre u <
dom_pre v)%
Z set.
Proof.