(* This file was originally generated by why.
   It can be modified; only the generated parts will be overwritten. *)
Require Export Why.

(*Why type*) Definition set: Set ->Set.
Admitted.

(*Why logic*) Definition set_empty : forall (A1:Set), (set A1).
Admitted.
Set Contextual Implicit.
Implicit Arguments set_empty.
Unset Contextual Implicit.

(*Why logic*) Definition set_add :
  forall (A1:Set), A1 -> (set A1) -> (set A1).
Admitted.
Implicit Arguments set_add.

(*Why logic*) Definition set_rmv :
  forall (A1:Set), A1 -> (set A1) -> (set A1).
Admitted.
Implicit Arguments set_rmv.

(*Why logic*) Definition In : forall (A1:Set), A1 -> (set A1) -> Prop.
Admitted.
Implicit Arguments In.

(*Why predicate*) Definition Is_empty (A158:Set) (s:(set A158))
  := (forall (x:A158), ~(In x s)).
Implicit Arguments Is_empty.

(*Why predicate*) Definition Incl (A159:Set) (s1:(set A159)) (s2:(set A159))
  := (forall (x:A159), ((In x s1) -> (In x s2))).
Implicit Arguments Incl.

(*Why axiom*) Lemma set_empty_def :
  forall (A1:Set), (Is_empty (@set_empty A1)).
Admitted.

(*Why axiom*) Lemma set_add_def :
  forall (A1:Set),
  (forall (x:A1),
   (forall (y:A1),
    (forall (s:(set A1)), ((In x (set_add y s)) <-> x = y \/ (In x s))))).
Admitted.

(*Why axiom*) Lemma set_rmv_def :
  forall (A1:Set),
  (forall (x:A1),
   (forall (y:A1),
    (forall (s:(set A1)), ((In x (set_rmv y s)) <-> ~(x = y) /\ (In x s))))).
Admitted.

(*Why logic*) Definition set_card : forall (A1:Set), (set A1) -> Z.
Admitted.
Implicit Arguments set_card.

(*Why axiom*) Lemma card_nonneg :
  forall (A1:Set), (forall (s:(set A1)), (set_card s) >= 0).
Admitted.

(*Why axiom*) Lemma card_set_add :
  forall (A1:Set),
  (forall (x:A1),
   (forall (s:(set A1)),
    (~(In x s) -> (set_card (set_add x s)) = (1 + (set_card s))))).
Admitted.

(*Why axiom*) Lemma card_set_rmv :
  forall (A1:Set),
  (forall (x:A1),
   (forall (s:(set A1)),
    ((In x s) -> (set_card s) = (1 + (set_card (set_rmv x s)))))).
Admitted.


(*Why axiom*) Lemma card_Incl :
  forall (A1:Set),
  (forall (s1:(set A1)),
   (forall (s2:(set A1)), ((Incl s1 s2) -> (set_card s1) <= (set_card s2)))).
Admitted.

(*Why type*) Definition map: Set -> Set ->Set.
Admitted.

(*Why logic*) Definition map_get :
  forall (A1:Set), forall (A2:Set), (map A2 A1) -> A2 -> A1.
Admitted.
Implicit Arguments map_get.

(*Why logic*) Definition map_set :
  forall (A1:Set), forall (A2:Set), (map A1 A2) -> A1 -> A2 -> (map A1 A2).
Admitted.
Implicit Arguments map_set.

(*Why axiom*) Lemma map_get_set_eq :
  forall (A1:Set), forall (A2:Set),
  (forall (m:(map A1 A2)),
   (forall (i:A1), (forall (v:A2), (map_get (map_set m i v) i) = v))).
Admitted.

(*Why axiom*) Lemma map_get_set_neq :
  forall (A1:Set), forall (A2:Set),
  (forall (m:(map A1 A2)),
   (forall (i:A1),
    (forall (j:A1),
     (forall (v:A2),
      (~(i = j) -> (map_get (map_set m i v) j) = (map_get m j)))))).
Admitted.

(*Why type*) Definition vertex: Set.
Admitted.

Axiom vertex_eq_dec : forall x y : vertex, {x=y}+{~x=y}.

(*Why logic*) Definition V : (set vertex).
Admitted.

(*Why logic*) Definition g_succ : vertex -> (set vertex).
Admitted.

(*Why axiom*) Lemma g_succ_sound : (forall (x:vertex), (Incl (g_succ x) V)).
Admitted.

(*Why logic*) Definition weight : vertex -> vertex -> Z.
Admitted.

(*Why axiom*) Lemma weight_nonneg :
  (forall (x:vertex), (forall (y:vertex), (weight x y) >= 0)).
Admitted.

(*Why predicate*) Definition Min  (m:vertex) (Q:(set vertex)) (d:(map vertex Z))
  := (In m Q) /\
     (forall (x:vertex), ((In x Q) -> (map_get d x) <= (map_get d m))).

(*Why logic*) Definition path : vertex -> vertex -> Z -> Prop.
Admitted.

(*Why axiom*) Lemma path_nil : (forall (x:vertex), (path x x 0)).
Admitted.

(*Why axiom*) Lemma path_cons :
  (forall (x:vertex),
   (forall (y:vertex),
    (forall (z:vertex),
     (forall (d:Z),
      ((path x y d) -> ((In z (g_succ y)) -> (path x z (d + (weight y z))))))))).
Admitted.

(*Why axiom*) Lemma length_nonneg :
  (forall (x:vertex),
   (forall (y:vertex), (forall (d:Z), ((path x y d) -> d >= 0)))).
Admitted.

(*Why predicate*) Definition shortest_path  (x:vertex) (y:vertex) (d:Z)
  := (path x y d) /\ (forall (d':Z), ((path x y d') -> d <= d')).

(*Why axiom*) Lemma path_inversion :
  (forall (src:vertex),
   (forall (v:vertex),
    (forall (d:Z),
     ((path src v d) -> v = src /\ d = 0 \/
      (exists v':vertex, (path src v' (d - (weight v' v))) /\
       (In v (g_succ v'))))))).
Admitted.

(*Why axiom*) Lemma path_shortest_path :
  (forall (src:vertex),
   (forall (v:vertex),
    (forall (d:Z),
     ((path src v d) -> (exists d':Z, (shortest_path src v d') /\ d' <= d))))).
Admitted.

(*Why axiom*) Lemma main_lemma :
  (forall (src:vertex),
   (forall (v:vertex),
    (forall (d:Z),
     ((path src v d) ->
      (~(shortest_path src v d) ->
       (exists v':vertex,
        (exists d':Z, (shortest_path src v' d') /\ (In v (g_succ v')) /\
         (d' + (weight v' v)) < d))))))).
Admitted.

(*Why axiom*) Lemma completeness_lemma :
  (forall (s:(set vertex)),
   (forall (src:vertex),
    (forall (dst:vertex),
     (forall (d:Z),
      ((forall (v:vertex),
        ((In v s) -> (forall (w:vertex), ((In w (g_succ v)) -> (In w s))))) ->
       ((In src s) -> ((path src dst d) -> (In dst s)))))))).
Admitted.



(*Why predicate*) Definition Inv_src  (src:vertex) (S:(set vertex)) (Q:(set vertex))
  := (In src S) \/ (In src Q).

(*Why predicate*) Definition Inv  (src:vertex) (S:(set vertex)) (Q:(set vertex)) (d:(map vertex Z))
  := (Inv_src src S Q) /\ (Incl S V) /\ (Incl Q V) /\
     (forall (v:vertex), ((In v Q) -> ((In v S) -> False))) /\
     (forall (v:vertex), ((In v S) -> (shortest_path src v (map_get d v)))) /\
     (forall (v:vertex), ((In v Q) -> (path src v (map_get d v)))) /\
     (forall (m:vertex),
      ((Min m Q d) ->
       (forall (x:vertex),
        (forall (dx:Z),
         ((shortest_path src x dx) -> (dx < (map_get d m) -> (In x S))))))).

(*Why predicate*) Definition InvSucc  (src:vertex) (S:(set vertex)) (Q:(set vertex))
  := (forall (x:vertex),
      ((In x S) ->
       (forall (y:vertex), ((In y (g_succ x)) -> (In y S) \/ (In y Q))))).


(*Why predicate*) Definition InvSucc2  (src:vertex) (S:(set vertex)) (Q:(set vertex)) (u:vertex) (su:(set vertex))
  := (forall (x:vertex),
      ((In x S) ->
       (forall (y:vertex),
        ((In y (g_succ x)) ->
         (~(x = u) \/ x = u /\ ~(In y su) -> (In y S) \/ (In y Q)))))).

Proof.
unfold Inv,Inv_src; intuition.
right; subst Q.
generalize (set_add_def _ src src set_empty); intuition.
unfold Incl; intros.
subst S; generalize (set_empty_def _ x); unfold Is_empty; intuition.
unfold Incl; intros.
subst Q; generalize (set_add_def _ x src set_empty); intuition.
subst x; auto.
generalize (set_empty_def _ x); unfold Is_empty; intuition.
subst S; generalize (set_empty_def _ v); unfold Is_empty; intuition.
(* sp *)
subst d0.
assert (v = src).
subst S; generalize (set_add_def _ v src set_empty); intuition.
generalize (set_empty_def _ v); unfold Is_empty; intuition.
subst v; rewrite map_get_set_eq.
unfold shortest_path; intuition.
apply path_nil.
apply Zge_le.
apply length_nonneg with src src; auto.
subst Q; generalize (set_add_def _ v src set_empty); intuition.
subst d0 v; rewrite map_get_set_eq.
apply path_nil.
generalize (set_empty_def _ v); unfold Is_empty; intuition.
unfold Min in H2; destruct H2.
(* In x S *)
assert (m = src).
subst Q; generalize (set_add_def _ m src set_empty); intuition.
generalize (set_empty_def _ m); unfold Is_empty; intuition.
subst m.
assert (dx >= 0).
apply length_nonneg with src x.
red in H5; intuition.
subst d0; rewrite map_get_set_eq in H6.
absurd (dx < 0); omega.
Qed.

Proof.
(* FILL PROOF HERE *)
Admitted.

Proof.
(* FILL PROOF HERE *)
Admitted.

Proof.
intros; red; intro hv.
assert (In v S0).
apply (completeness_lemma S0 src v dv).
unfold Inv,InvSucc in *|-*; intuition.
destruct (H4 v0 H11 w H13).
auto.
unfold Is_empty in HW_4; absurd (In w Q0); intuition.
eauto.
unfold Inv,Inv_src in *|-*; intuition.
unfold Is_empty in HW_4; absurd (In src Q0); intuition.
eauto.
auto.
intuition.
Qed.

Proof.
(****
  unfold Inv; intuition.
  generalize (H8 result H9); clear H8.
  unfold Min in H9; red; intuition.
  assert (case : fst result = src \/ fst result <> src). omega.  destruct case.
  destruct result as (v,d).
  subst src.
  generalize (H7 d H12); clear H7; destruct 1.
  elim (HW_9 H7).
  simpl; subst d.
  apply Zge_le. apply length_nonneg with v v; assumption.
 (* v <> src *)
 destruct result as (v,d); simpl in *|-*.
  destruct (path_inversion _ _ _ H9); intuition.
  destruct H15 as (v',(hv'1,hv'2)).
  assert (case : d' < d \/ d <= d'). omega. intuition.
  generalize (path_shortest_path _ _ _ hv'1); intros (d'',(h''1,h''2)).
  assert (In v' visited0).
  apply H8 with d''; auto.
  assert (weight v' v >= 0).
  apply weight_nonneg.
 omega.
  generalize (H10 v' v H16 hv'2); intuition.
  assert (h := H18 d'' h''1).
  pose (H13 _ h).
  simpl in z. omega.
Save.
***)
Admitted.

Proof.
(***
  unfold Inv; intuition; subst dst.
  assumption.
Save.
***)
Admitted.

Proof.
  unfold InvSucc,InvSucc2; intuition.
  assert (In x S0).
  generalize (set_add_def _ x result S0); subst S1; intuition.
  destruct (H5 x H10 y H9); intuition.
  left; subst S1; generalize (set_add_def _ y result S0); intuition.
  destruct (vertex_eq_dec y result).
  subst y S1; left.
  generalize (set_add_def _ result result S0); intuition.
  right; generalize (set_rmv_def _ y result Q0); subst Q1; intuition.
  


(*********
  unfold Inv, Min, MinNotVisited; intuition.
  unfold Inv_src in *|-*; intuition.
  destruct (vertex_eq_dec (fst result) src); intuition.  
  subst src; intuition.
  assert (pair src 0 <> result).
  red; intros; apply n.
  subst result; auto.
  right. generalize (set_rmv_def _ (pair src 0) result pq1); subst pq2; intuition.

  assert (In e pq1). generalize (set_rmv_def _ e result pq1); subst pq2; intuition. 
  intuition.

  assert (m <> result). intuition.
  subst m; intuition.
  assert (In m pq1). generalize (set_rmv_def _ m result pq1); subst pq2; intuition.
  apply (H8 m) with d; intuition.
  apply H14; intuition.
  assert (x0 <> result).
  intuition. subst x0; intuition.
  generalize (set_rmv_def _ x0 result pq1); subst pq2; intuition.
Save.
***************)


Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

Proof.
(* FILL PROOF HERE *)
Save.

