@@ -74,16 +74,21 @@ lemma berge_vpath_of_epath:
7474 shows "P = vpath_of_epath (dedges_of_path P)"
7575 using assms by ( induction P rule : list0123.induct ) auto
7676
77- lemma walk_vpath_elim :
77+ lemma vpath_of_epath_cancel :
78+ "dedges_of_path (vpath_of_epath (dedges_of_path P\<^sub>v)) = dedges_of_path P\<^sub>v"
79+ by ( induction P \<^sub >v rule : list0123.induct ) auto
80+
81+ lemma walk_vpath_elim_epath :
7882 assumes "walk_betw E u P\<^sub>v v"
79- obtains "P\<^sub>v = [u]" "u = v" | P where "P\<^sub>v = vpath_of_epath P"
83+ obtains "P\<^sub>v = [u]" "u = v"
84+ | P where "P\<^sub>v = vpath_of_epath P" "dedges_of_path (vpath_of_epath P) = P"
8085 using assms walk_between_nonempty_path [ OF assms ( 1 )]
8186proof ( induction P \<^sub >v rule : list012.induct )
8287 case ( 3 u v P \<^sub >v )
8388 hence "u#v#P\<^sub>v = vpath_of_epath (dedges_of_path (u#v#P\<^sub>v))"
8489 by ( intro berge_vpath_of_epath ) auto
8590 then show ?case
86- using 3 by blast
91+ using 3 vpath_of_epath_cancel by metis
8792qed auto
8893
8994lemma prim_vpath_of_epath :
@@ -108,6 +113,15 @@ lemma prim_vpath_of_epathE:
108113 obtains P' where "P = dedges_of_path P'"
109114 using assms prim_vpath_of_epath [ of G ] by auto
110115
116+ lemma epath_split_hd1 :
117+ assumes "dedges_of_path (vpath_of_epath (e\<^sub>1#e\<^sub>2#P)) = e\<^sub>1#e\<^sub>2#P" "hd (vpath_of_epath (e\<^sub>1#e\<^sub>2#P)) = u"
118+ obtains x where "e\<^sub>1 = (u,x)" "fst e\<^sub>2 = x"
119+ using assms by ( induction P ) fastforce +
120+
121+ lemma epath_split_hd2 :
122+ assumes "dedges_of_path (vpath_of_epath (e\<^sub>1#e\<^sub>2#P)) = e\<^sub>1#e\<^sub>2#P"
123+ obtains u x where "e\<^sub>1 = (u,x)" "fst e\<^sub>2 = x"
124+ using assms by ( induction P ) ( meson epath_split_hd1 )+
111125
112126
113127context graph_abs
@@ -366,13 +380,9 @@ begin
366380lemma st_equiv1 : "is_st T \<Longrightarrow> is_spanning_tree (prim_of_berge E) (prim_of_berge T)"
367381 using st_is_graph by ( intro graph_abs2.st_equiv1 ) unfold_locales
368382
369- lemma spanning_tree_is_graph :
370- assumes "is_spanning_tree (prim_of_berge E) (prim_of_berge T)"
371- shows "graph_invar T"
372- sorry (* TODO *)
373-
374- lemma st_equiv2 : "is_spanning_tree (prim_of_berge E) (prim_of_berge T) \<Longrightarrow> is_st T"
375- using spanning_tree_is_graph by ( intro graph_abs2.st_equiv2 ) unfold_locales
383+ lemma st_equiv2 :
384+ "graph_invar T \<Longrightarrow> is_spanning_tree (prim_of_berge E) (prim_of_berge T) \<Longrightarrow> is_st T"
385+ by ( intro graph_abs2.st_equiv2 ) unfold_locales
376386
377387end
378388
@@ -397,7 +407,7 @@ proof
397407qed
398408
399409lemma mst_equiv2 :
400- assumes "is_MST c (prim_of_berge E) (prim_of_berge T)"
410+ assumes "graph_invar T" " is_MST c (prim_of_berge E) (prim_of_berge T)"
401411 shows "is_mst T"
402412proof ( intro is_mstI )
403413 show "is_st T"
@@ -466,6 +476,9 @@ lemma edges_equiv1_uedge: "e \<in> edges G \<Longrightarrow> uedge e \<in> berge
466476lemma edges_equiv2 : "{u,v} \<in> berge_of_prim G \<Longrightarrow> (u,v) \<in> edges G"
467477 using berge_edges_invar by ( metis doubleton_eq_iff edges_sym' )+
468478
479+ lemma edges_equiv2_uedge : "uedge e \<in> berge_of_prim G \<Longrightarrow> e \<in> edges G"
480+ unfolding uedge_def using edges_equiv2 by ( auto split : prod.splits )
481+
469482lemma berge_of_prim_def2 : "berge_of_prim G = {{u,v} | u v. (u,v) \<in> edges G}"
470483 unfolding berge_of_prim_def by ( auto simp add : uedge_def )
471484
@@ -521,27 +534,49 @@ lemma path_edges_subset2:
521534 shows "set (edges_of_path P) \<subseteq> berge_of_prim G"
522535 using assms by ( induction P rule : dedges_of_path.induct ) ( auto simp : berge_of_prim_def2 )
523536
524- thm induct_walk_betw
525-
526- lemma berge_walk_is_prim_path :
527- assumes "walk_betw (berge_of_prim G) u (vpath_of_epath P) v" ( is "walk_betw ?E u ?P v" )
528- shows "Undirected_Graph.path G u P v"
537+ lemma berge_vpath_hd_of_epath_is_prim_edge :
538+ assumes "path (berge_of_prim G) (vpath_of_epath (e#P))" ( is "path ?E _" )
539+ and "dedges_of_path (vpath_of_epath (e#P)) = (e#P)"
540+ shows "e \<in> edges G"
529541 using assms
530- proof ( induction u "vpath_of_epath P" v arbitrary : P rule : induct_walk_betw )
531- case ( path1 v )
542+ proof ( induction P )
543+ case Nil
544+ then obtain u v where [ simp ]: "e = (u,v)" and "path ?E [u,v]"
545+ by ( cases e ) auto
532546 thus ?case
533- by ( auto elim : vpath_of_epathE )
547+ by ( intro edges_equiv2_uedge ) ( auto simp : uedge_def )
534548next
535- case ( path2 u v P \<^sub >v w )
536-
537- hence "(u,v) \<in> edges G"
538- by ( intro edges_equiv2 )
539-
540-
541- thm vpath_of_epathE
549+ case ( Cons e \<^sub >1 P )
550+ then obtain u x where [ simp ]: "e = (u,x)" and [ simp ]: "fst e\<^sub>1 = x"
551+ by ( elim epath_split_hd2 )
552+ hence "uedge e \<in> ?E"
553+ using Cons path_edges_subset by ( auto simp : uedge_def )
554+ thus ?case
555+ by ( intro edges_equiv2_uedge )
556+ qed
542557
543- then show ?case
544- sorry
558+ lemma berge_walk_is_prim_path :
559+ assumes "walk_betw (berge_of_prim G) u (vpath_of_epath P) v" ( is "walk_betw ?E u _ v" )
560+ and "dedges_of_path (vpath_of_epath P) = P"
561+ shows "Undirected_Graph.path G u P v"
562+ using walk_between_nonempty_path [ OF assms ( 1 )] assms ( 2 )
563+ proof ( induction P arbitrary : u rule : list012.induct )
564+ case 1
565+ thus ?case using walk_nonempty by fastforce
566+ next
567+ case ( 2 e )
568+ moreover hence "e \<in> edges G"
569+ by ( intro berge_vpath_hd_of_epath_is_prim_edge )
570+ ultimately show ?case
571+ by auto
572+ next
573+ case ( 3 e \<^sub >1 e \<^sub >2 P )
574+ then obtain x where [ simp ]: "e\<^sub>1 = (u,x)" and [ simp ]: "fst e\<^sub>2 = x"
575+ by ( elim epath_split_hd1 )
576+ moreover have "e\<^sub>1 \<in> edges G"
577+ using 3 by ( intro berge_vpath_hd_of_epath_is_prim_edge [ of e \<^sub >1 "e\<^sub>2#P" ])
578+ ultimately show ?case
579+ using 3 by auto
545580qed
546581
547582lemma prim_path_is_berge_path :
@@ -585,14 +620,17 @@ lemma walk_iff_rtrancl_edges:
585620 shows "(\<exists>P. walk_betw (berge_of_prim G) u P v) \<longleftrightarrow> (u,v) \<in> (edges G)\<^sup>*"
586621proof
587622 assume "\<exists>P. walk_betw (berge_of_prim G) u P v"
588- then obtain P \<^sub >v where "walk_betw (berge_of_prim G) u P\<^sub>v v"
623+ then obtain P \<^sub >v where "walk_betw (berge_of_prim G) u P\<^sub>v v"
589624 by auto
590- then consider "P\<^sub>v = [u]" "u = v" | P where "walk_betw (berge_of_prim G) u (vpath_of_epath P) v"
591- by ( auto elim : walk_vpath_elim )
625+ then consider "P\<^sub>v = [u]" "u = v"
626+ | P where "walk_betw (berge_of_prim G) u (vpath_of_epath P) v"
627+ "dedges_of_path (vpath_of_epath P) = P"
628+ by ( auto elim : walk_vpath_elim_epath )
592629 thus "(u,v) \<in> (edges G)\<^sup>*"
593630 proof cases
594631 fix P
595- assume "walk_betw (berge_of_prim G) u (vpath_of_epath P) v"
632+ assume "walk_betw (berge_of_prim G) u (vpath_of_epath P) v"
633+ "dedges_of_path (vpath_of_epath P) = P"
596634 thus "(u,v) \<in> (edges G)\<^sup>*"
597635 using berge_walk_is_prim_path by ( intro iffD2 [ OF rtrancl_edges_iff_path ]) auto
598636 qed auto
@@ -728,7 +766,7 @@ proof (rule ccontr)
728766 moreover have "walk_betw (berge_of_prim G) u (vpath_of_epath (dedges_of_path C)) u"
729767 using calculation by ( subst berge_vpath_of_epath [ symmetric ]) auto
730768 moreover hence "Undirected_Graph.path G u (dedges_of_path C) u"
731- by ( intro berge_walk_is_prim_path )
769+ using vpath_of_epath_cancel by ( intro berge_walk_is_prim_path )
732770 moreover have "dedges_of_path C \<noteq> []"
733771 using calculation by ( auto simp : dedges_length [ symmetric ])
734772 moreover have "simple (dedges_of_path C)"
@@ -745,148 +783,6 @@ lemma tree_equiv2: "tree G \<Longrightarrow> is_tree (berge_of_prim G)"
745783
746784end
747785
748-
749- (* TODO ... *)
750-
751- context graph_abs
752- begin
753-
754- text \<open>Convert to graph from \<open>Prim_Dijkstra_Simple\<close> . \<close>
755- abbreviation "G\<^sub>E \<equiv> Undirected_Graph.graph (Vs E) {(u,v)| u v. {u,v} \<in> E}"
756-
757- end
758-
759- locale st_graph_abs = (* spanning tree equivalence *)
760- E : graph_abs E +
761- T : graph_abs T for E :: "'a set set " and T :: "'a set set"
762- begin
763-
764- lemma edges_subset_iff : "T \<subseteq> E \<longleftrightarrow> edges T.G\<^sub>E \<subseteq> edges E.G\<^sub>E"
765- proof
766- assume "T \<subseteq> E"
767- show "edges T.G\<^sub>E \<subseteq> edges E.G\<^sub>E"
768- proof
769- fix x
770- assume "x \<in> edges T.G\<^sub>E"
771- moreover then obtain u v where [ simp ]: "x = (u,v)"
772- using old.prod.exhaust by blast
773- ultimately show "x \<in> edges E.G\<^sub>E"
774- using T.edges_equiv [ of u v ] \<open>T \<subseteq> E\<close> E.edges_equiv [ of u v ] by auto
775- qed
776- next
777- assume "edges T.G\<^sub>E \<subseteq> edges E.G\<^sub>E"
778- show "T \<subseteq> E"
779- proof
780- fix x
781- assume "x \<in> T"
782- moreover then obtain u v where [ simp ]: "x = {u,v}"
783- using T.graph by auto
784- ultimately show "x \<in> E"
785- using T.edges_equiv [ of u v ] \<open>edges T.G\<^sub>E \<subseteq> edges E.G\<^sub>E\<close> E.edges_equiv [ of u v ] by auto
786- qed
787- qed
788-
789- lemma st_equiv : "E.is_st T \<longleftrightarrow> is_spanning_tree E.G\<^sub>E T.G\<^sub>E"
790- apply ( rule iffI )
791- using T.tree_equiv E.nodes_equiv T.nodes_equiv edges_subset_iff
792- by ( auto intro : E.is_stI simp : E.is_stE is_spanning_tree_def )
793-
794- lemma st_equiv2 : "E.is_st (uedge ` edges T.G\<^sub>E) \<longleftrightarrow> is_spanning_tree E.G\<^sub>E T.G\<^sub>E"
795- using st_equiv by ( subst T.edges_equiv2 [ symmetric ])
796-
797- end
798-
799- context graph_abs
800- begin
801-
802- lemma st_equiv :
803- fixes T
804- defines "G\<^sub>T \<equiv> graph (Vs T) {(u, v) |u v. {u, v} \<in> T}"
805- assumes "graph_invar T"
806- shows "is_st T \<longleftrightarrow> is_spanning_tree G\<^sub>E G\<^sub>T"
807- unfolding G \<^sub >T_def using assms by ( intro st_graph_abs.st_equiv ) unfold_locales
808-
809- lemma st_equiv2 :
810- fixes G \<^sub >T
811- assumes "graph_invar (uedge ` edges G\<^sub>T)"
812- shows "is_st (uedge ` edges G\<^sub>T) \<longleftrightarrow> is_spanning_tree G\<^sub>E G\<^sub>T"
813- using st_graph_abs.st_equiv2
814- apply ( intro st_graph_abs.st_equiv2 )
815- sorry
816-
817- end
818-
819- locale nat_w_graph_abs = (* nat weights *)
820- pos_w_graph_abs E c for E :: "'a set set" and c :: "'a set \<Rightarrow> nat"
821- begin
822-
823- lemma cost_of_st_equiv :
824- fixes T
825- defines "G\<^sub>T \<equiv> graph (Vs T) {(u, v) |u v. {u, v} \<in> T}"
826- assumes "graph_invar T"
827- shows "cost_of_st T = weight c G\<^sub>T"
828- proof -
829- have "cost_of_st T = sum c (uedge ` edges G\<^sub>T)"
830- using assms graph_abs.edges_equiv2 [ unfolded graph_abs_def , of T ] by auto
831- also have "... = Undirected_Graph.weight c G\<^sub>T"
832- unfolding Undirected_Graph.weight_alt by auto
833- finally show ?thesis .
834- qed
835-
836- lemma mst_equiv :
837- fixes T
838- defines "G\<^sub>T \<equiv> graph (Vs T) {(u, v) |u v. {u, v} \<in> T}"
839- assumes "graph_invar T"
840- shows "is_mst T \<longleftrightarrow> is_MST c G\<^sub>E G\<^sub>T"
841- proof
842- assume "is_mst T"
843- hence "is_st T" and min_st : "\<And>T'. is_st T' \<Longrightarrow> cost_of_st T \<le> cost_of_st T'"
844- by ( auto elim : is_mstE )
845- moreover hence "is_spanning_tree G\<^sub>E G\<^sub>T"
846- using assms st_equiv [ OF st_graph_invar ] by auto
847- moreover have "\<And>T'. is_spanning_tree G\<^sub>E T' \<Longrightarrow> weight c G\<^sub>T \<le> weight c T'"
848- proof -
849- fix T'
850- assume "is_spanning_tree G\<^sub>E T'"
851- hence "is_st (uedge ` edges T')"
852- apply ( intro st_equiv2 )
853- sorry
854-
855- show "weight c G\<^sub>T \<le> weight c T'"
856-
857- using assms st_equiv cost_of_st_equiv [ OF st_graph_invar ]
858- sorry
859- qed
860- ultimately show "is_MST c G\<^sub>E G\<^sub>T"
861- unfolding is_MST_def by auto
862- next
863- assume "is_MST c G\<^sub>E G\<^sub>T"
864- hence "is_spanning_tree G\<^sub>E G\<^sub>T"
865- and min_st : "\<And>G\<^sub>T'. is_spanning_tree G\<^sub>E G\<^sub>T' \<Longrightarrow> weight c G\<^sub>T \<le> weight c G\<^sub>T'"
866- unfolding is_MST_def by auto
867- moreover hence st_T : "is_st T"
868- using assms st_equiv [ OF st_graph_invar ] sorry
869- moreover have "\<And>T'. is_st T' \<Longrightarrow> cost_of_st T \<le> cost_of_st T'"
870- proof -
871- fix T'
872- assume st_T' : "is_st T'"
873- hence st_G \<^sub >T : "is_spanning_tree G\<^sub>E (graph (Vs T') {(u, v) |u v. {u, v} \<in> T'})"
874- ( is "is_spanning_tree G\<^sub>E ?G\<^sub>T'" )
875- using assms st_equiv [ OF st_graph_invar ] by auto
876- have "cost_of_st T = weight c G\<^sub>T"
877- unfolding G \<^sub >T_def using st_T by ( intro cost_of_st_equiv [ OF st_graph_invar ])
878- also have "... \<le> weight c ?G\<^sub>T'"
879- using min_st st_G \<^sub >T by auto
880- also have "... = cost_of_st T'"
881- using st_T' by ( intro cost_of_st_equiv [ OF st_graph_invar , symmetric ])
882- finally show "cost_of_st T \<le> cost_of_st T'" .
883- qed
884- ultimately show "is_mst T"
885- by ( intro is_mstI )
886- qed (* TODO: fix locale stuff *)
887-
888- end
889-
890786(* TODO: use Prim_Dijkstra_Simple implementation *)
891787
892788fun prim_impl' where
0 commit comments