(* This file is generated by Why3's Coq driver *)
(* Beware! Only edit allowed sections below    *)
Require Import BuiltIn.
Require BuiltIn.
Require int.Int.

Axiom set : forall (a:Type), Type.
Parameter set_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (set a).
Existing Instance set_WhyType.

Parameter mem: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> Prop.

Parameter infix_eqeq: forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) ->
  Prop.

Axiom infix_eqeq_spec : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (infix_eqeq s1 s2) <-> forall (x:a), (mem x s1) <-> (mem x
  s2).

Axiom extensionality : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (infix_eqeq s1 s2) -> (s1 = s2).

Parameter subset: forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) ->
  Prop.

Axiom subset_spec : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (subset s1 s2) <-> forall (x:a), (mem x s1) -> (mem x s2).

Axiom subset_refl : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  (subset s s).

Axiom subset_trans : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)) (s3:(set a)), (subset s1 s2) -> ((subset s2 s3) -> (subset s1
  s3)).

Parameter is_empty: forall {a:Type} {a_WT:WhyType a}, (set a) -> Prop.

Axiom is_empty_spec : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  (is_empty s) <-> forall (x:a), ~ (mem x s).

Parameter empty: forall {a:Type} {a_WT:WhyType a}, (set a).

Axiom empty_def : forall {a:Type} {a_WT:WhyType a}, (is_empty (empty : (set
  a))).

Parameter add: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> (set a).

Axiom add_spec : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (s:(set a)),
  forall (y:a), (mem y (add x s)) <-> ((y = x) \/ (mem y s)).

Parameter remove: forall {a:Type} {a_WT:WhyType a}, a -> (set a) -> (set a).

Axiom remove_spec : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (s:(set
  a)), forall (y:a), (mem y (remove x s)) <-> ((~ (y = x)) /\ (mem y s)).

Axiom add_remove : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (s:(set
  a)), (mem x s) -> ((add x (remove x s)) = s).

Axiom remove_add : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (s:(set
  a)), ((remove x (add x s)) = (remove x s)).

Axiom subset_remove : forall {a:Type} {a_WT:WhyType a}, forall (x:a) (s:(set
  a)), (subset (remove x s) s).

Parameter union: forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> (set
  a).

Axiom union_spec : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), forall (x:a), (mem x (union s1 s2)) <-> ((mem x s1) \/ (mem x
  s2)).

Parameter inter: forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> (set
  a).

Axiom inter_spec : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), forall (x:a), (mem x (inter s1 s2)) <-> ((mem x s1) /\ (mem x
  s2)).

Parameter diff: forall {a:Type} {a_WT:WhyType a}, (set a) -> (set a) -> (set
  a).

Axiom diff_spec : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), forall (x:a), (mem x (diff s1 s2)) <-> ((mem x s1) /\ ~ (mem
  x s2)).

Axiom subset_diff : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (subset (diff s1 s2) s1).

Parameter choose: forall {a:Type} {a_WT:WhyType a}, (set a) -> a.

Axiom choose_spec : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  (~ (is_empty s)) -> (mem (choose s) s).

Parameter cardinal: forall {a:Type} {a_WT:WhyType a}, (set a) -> Z.

Axiom cardinal_nonneg : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  (0%Z <= (cardinal s))%Z.

Axiom cardinal_empty : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  ((cardinal s) = 0%Z) <-> (is_empty s).

Axiom cardinal_add : forall {a:Type} {a_WT:WhyType a}, forall (x:a),
  forall (s:(set a)), (~ (mem x s)) -> ((cardinal (add x
  s)) = (1%Z + (cardinal s))%Z).

Axiom cardinal_remove : forall {a:Type} {a_WT:WhyType a}, forall (x:a),
  forall (s:(set a)), (mem x s) -> ((cardinal s) = (1%Z + (cardinal (remove x
  s)))%Z).

Axiom cardinal_subset : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (subset s1 s2) -> ((cardinal s1) <= (cardinal s2))%Z.

Axiom subset_eq : forall {a:Type} {a_WT:WhyType a}, forall (s1:(set a))
  (s2:(set a)), (subset s1 s2) -> (((cardinal s1) = (cardinal s2)) ->
  (infix_eqeq s1 s2)).

Axiom cardinal1 : forall {a:Type} {a_WT:WhyType a}, forall (s:(set a)),
  ((cardinal s) = 1%Z) -> forall (x:a), (mem x s) -> (x = (choose s)).

Axiom vertex : Type.
Parameter vertex_WhyType : WhyType vertex.
Existing Instance vertex_WhyType.

Parameter eq: vertex -> vertex -> Prop.

Axiom eq_spec : forall (x:vertex) (y:vertex), (eq x y) <-> (x = y).

Parameter succ: vertex -> (set vertex).

(* Why3 assumption *)
Inductive path: vertex -> vertex -> Z -> Prop :=
  | path_empty : forall (v:vertex), (path v v 0%Z)
  | path_succ : forall (v1:vertex) (v2:vertex) (v3:vertex) (n:Z), (path v1 v2
      n) -> ((mem v3 (succ v2)) -> (path v1 v3 (n + 1%Z)%Z)).

Axiom path_nonneg : forall (v1:vertex) (v2:vertex) (n:Z), (path v1 v2 n) ->
  (0%Z <= n)%Z.

Axiom path_inversion : forall (v1:vertex) (v3:vertex) (n:Z), (0%Z <= n)%Z ->
  ((path v1 v3 (n + 1%Z)%Z) -> exists v2:vertex, (path v1 v2 n) /\ (mem v3
  (succ v2))).

Axiom path_closure : forall (s:(set vertex)), (forall (x:vertex), (mem x
  s) -> forall (y:vertex), (mem y (succ x)) -> (mem y s)) ->
  forall (v1:vertex) (v2:vertex) (n:Z), (path v1 v2 n) -> ((mem v1 s) -> (mem
  v2 s)).

(* Why3 assumption *)
Definition shortest_path (v1:vertex) (v2:vertex) (n:Z): Prop := (path v1 v2
  n) /\ forall (m:Z), (m < n)%Z -> ~ (path v1 v2 m).

Axiom t : Type.
Parameter t_WhyType : WhyType t.
Existing Instance t_WhyType.

Parameter contents: t -> (set vertex).

Parameter is_empty1: t -> Prop.

Axiom is_empty_spec1 : forall (s:t), (is_empty1 s) <-> (is_empty
  (contents s)).

Parameter mem1: vertex -> t -> Prop.

Axiom mem_spec : forall (x:vertex) (s:t), (mem1 x s) <-> (mem x
  (contents s)).

Parameter cardinal2: t -> Z.

Axiom cardinal_spec : forall (s:t),
  ((cardinal2 s) = (cardinal (contents s))).

(* Why3 assumption *)
Inductive ref (a:Type) :=
  | mk_ref : a -> ref a.
Axiom ref_WhyType : forall (a:Type) {a_WT:WhyType a}, WhyType (ref a).
Existing Instance ref_WhyType.
Implicit Arguments mk_ref [[a]].

(* Why3 assumption *)
Definition contents1 {a:Type} {a_WT:WhyType a} (v:(ref a)): a :=
  match v with
  | (mk_ref x) => x
  end.

(* Why3 assumption *)
Definition inv (s:vertex) (t1:vertex) (visited:(set vertex)) (current:(set
  vertex)) (next:(set vertex)) (d:Z): Prop := (subset current visited) /\
  ((forall (x:vertex), (mem x current) -> (shortest_path s x d)) /\ ((subset
  next visited) /\ ((forall (x:vertex), (mem x next) -> (shortest_path s x
  (d + 1%Z)%Z)) /\ ((forall (x:vertex) (m:Z), (path s x m) -> ((m <= d)%Z ->
  (mem x visited))) /\ ((forall (x:vertex), (mem x visited) -> exists m:Z,
  (path s x m) /\ (m <= (d + 1%Z)%Z)%Z) /\ ((forall (x:vertex),
  (shortest_path s x (d + 1%Z)%Z) -> ((mem x next) \/ ~ (mem x visited))) /\
  ((mem t1 visited) -> ((mem t1 current) \/ (mem t1 next))))))))).

(* Why3 assumption *)
Definition closure (visited:(set vertex)) (current:(set vertex)) (next:(set
  vertex)) (x:vertex): Prop := (mem x visited) -> ((~ (mem x current)) ->
  ((~ (mem x next)) -> forall (y:vertex), (mem y (succ x)) -> (mem y
  visited))).

(* Why3 goal *)
Theorem VC_bfs : forall (s:vertex) (t1:vertex), forall (visited:t), (is_empty
  (contents visited)) -> forall (o:t), (is_empty (contents o)) ->
  forall (o1:t), (is_empty (contents o1)) -> forall (visited1:t),
  ((contents visited1) = (add s (contents visited))) -> forall (current:t),
  ((contents current) = (add s (contents o))) -> forall (d:Z) (next:t)
  (current1:t) (visited2:t), ((inv s t1 (contents visited2)
  (contents current1) (contents next) d) /\ (((is_empty
  (contents current1)) -> (is_empty (contents next))) /\ ((forall (x:vertex),
  (closure (contents visited2) (contents current1) (contents next) x)) /\
  (0%Z <= d)%Z))) -> (((is_empty1 current1) <-> (is_empty
  (contents current1))) -> ((is_empty1 current1) -> ((~ (mem t1
  (contents visited2))) -> forall (d1:Z), ~ (path s t1 d1)))).
Proof.
intros s t1 visited h1 o h2 o1 h3 visited1 h4 current h5 d next current1
visited2 (h6,(h7,(h8,h9))) h10 h11 h12 d1.
intuition.
assert (mem t1 (contents visited2)).
apply path_closure with s d1; auto.
unfold closure in h8.
intros x hx.
apply h8; intuition.
apply (proj1 (is_empty_spec _) H2 _ H1).
apply (proj1 (is_empty_spec _) H0 _ H1).
red in h6; decompose [and] h6.
apply H7 with 0%Z.
apply path_empty.
assumption.
exact (h12 H1).
Qed.

