src/HOL/Proofs/Extraction/Warshall.thy
changeset 63361 d10eab0672f9
parent 61986 2461779da2b8
child 66453 cc19f7ca2ed6
equal deleted inserted replaced
63360:65a9eb946ff2 63361:d10eab0672f9
    13   based on Berger, Schwichtenberg and Seisenberger @{cite "Berger-JAR-2001"}.
    13   based on Berger, Schwichtenberg and Seisenberger @{cite "Berger-JAR-2001"}.
    14 \<close>
    14 \<close>
    15 
    15 
    16 datatype b = T | F
    16 datatype b = T | F
    17 
    17 
    18 primrec
    18 primrec is_path' :: "('a \<Rightarrow> 'a \<Rightarrow> b) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool"
    19   is_path' :: "('a \<Rightarrow> 'a \<Rightarrow> b) \<Rightarrow> 'a \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool"
       
    20 where
    19 where
    21     "is_path' r x [] z = (r x z = T)"
    20   "is_path' r x [] z \<longleftrightarrow> r x z = T"
    22   | "is_path' r x (y # ys) z = (r x y = T \<and> is_path' r y ys z)"
    21 | "is_path' r x (y # ys) z \<longleftrightarrow> r x y = T \<and> is_path' r y ys z"
    23 
    22 
    24 definition
    23 definition is_path :: "(nat \<Rightarrow> nat \<Rightarrow> b) \<Rightarrow> (nat * nat list * nat) \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
    25   is_path :: "(nat \<Rightarrow> nat \<Rightarrow> b) \<Rightarrow> (nat * nat list * nat) \<Rightarrow>
    24   where "is_path r p i j k \<longleftrightarrow>
    26     nat \<Rightarrow> nat \<Rightarrow> nat \<Rightarrow> bool"
    25     fst p = j \<and> snd (snd p) = k \<and>
    27 where
    26     list_all (\<lambda>x. x < i) (fst (snd p)) \<and>
    28   "is_path r p i j k \<longleftrightarrow> fst p = j \<and> snd (snd p) = k \<and>
    27     is_path' r (fst p) (fst (snd p)) (snd (snd p))"
    29      list_all (\<lambda>x. x < i) (fst (snd p)) \<and>
    28 
    30      is_path' r (fst p) (fst (snd p)) (snd (snd p))"
    29 definition conc :: "'a \<times> 'a list \<times> 'a \<Rightarrow> 'a \<times> 'a list \<times> 'a \<Rightarrow> 'a \<times> 'a list * 'a"
    31 
    30   where "conc p q = (fst p, fst (snd p) @ fst q # fst (snd q), snd (snd q))"
    32 definition
    31 
    33   conc :: "('a * 'a list * 'a) \<Rightarrow> ('a * 'a list * 'a) \<Rightarrow> ('a * 'a list * 'a)"
    32 theorem is_path'_snoc [simp]: "\<And>x. is_path' r x (ys @ [y]) z = (is_path' r x ys y \<and> r y z = T)"
    34 where
       
    35   "conc p q = (fst p, fst (snd p) @ fst q # fst (snd q), snd (snd q))"
       
    36 
       
    37 theorem is_path'_snoc [simp]:
       
    38   "\<And>x. is_path' r x (ys @ [y]) z = (is_path' r x ys y \<and> r y z = T)"
       
    39   by (induct ys) simp+
    33   by (induct ys) simp+
    40 
    34 
    41 theorem list_all_scoc [simp]: "list_all P (xs @ [x]) \<longleftrightarrow> P x \<and> list_all P xs"
    35 theorem list_all_scoc [simp]: "list_all P (xs @ [x]) \<longleftrightarrow> P x \<and> list_all P xs"
    42   by (induct xs, simp+, iprover)
    36   by (induct xs) (simp+, iprover)
    43 
    37 
    44 theorem list_all_lemma: 
    38 theorem list_all_lemma: "list_all P xs \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> list_all Q xs"
    45   "list_all P xs \<Longrightarrow> (\<And>x. P x \<Longrightarrow> Q x) \<Longrightarrow> list_all Q xs"
       
    46 proof -
    39 proof -
    47   assume PQ: "\<And>x. P x \<Longrightarrow> Q x"
    40   assume PQ: "\<And>x. P x \<Longrightarrow> Q x"
    48   show "list_all P xs \<Longrightarrow> list_all Q xs"
    41   show "list_all P xs \<Longrightarrow> list_all Q xs"
    49   proof (induct xs)
    42   proof (induct xs)
    50     case Nil
    43     case Nil
    51     show ?case by simp
    44     show ?case by simp
    52   next
    45   next
    53     case (Cons y ys)
    46     case (Cons y ys)
    54     hence Py: "P y" by simp
    47     then have Py: "P y" by simp
    55     from Cons have Pys: "list_all P ys" by simp
    48     from Cons have Pys: "list_all P ys" by simp
    56     show ?case
    49     show ?case
    57       by simp (rule conjI PQ Py Cons Pys)+
    50       by simp (rule conjI PQ Py Cons Pys)+
    58   qed
    51   qed
    59 qed
    52 qed
    60 
    53 
    61 theorem lemma1: "\<And>p. is_path r p i j k \<Longrightarrow> is_path r p (Suc i) j k"
    54 theorem lemma1: "\<And>p. is_path r p i j k \<Longrightarrow> is_path r p (Suc i) j k"
    62   apply (unfold is_path_def)
    55   unfolding is_path_def
    63   apply (simp cong add: conj_cong add: split_paired_all)
    56   apply (simp cong add: conj_cong add: split_paired_all)
    64   apply (erule conjE)+
    57   apply (erule conjE)+
    65   apply (erule list_all_lemma)
    58   apply (erule list_all_lemma)
    66   apply simp
    59   apply simp
    67   done
    60   done
    68 
    61 
    69 theorem lemma2: "\<And>p. is_path r p 0 j k \<Longrightarrow> r j k = T"
    62 theorem lemma2: "\<And>p. is_path r p 0 j k \<Longrightarrow> r j k = T"
    70   apply (unfold is_path_def)
    63   unfolding is_path_def
    71   apply (simp cong add: conj_cong add: split_paired_all)
    64   apply (simp cong add: conj_cong add: split_paired_all)
    72   apply (case_tac "aa")
    65   apply (case_tac "aa")
    73   apply simp+
    66   apply simp+
    74   done
    67   done
    75 
    68 
    78 proof -
    71 proof -
    79   assume pys: "is_path' r i ys k"
    72   assume pys: "is_path' r i ys k"
    80   show "\<And>j. is_path' r j xs i \<Longrightarrow> is_path' r j (xs @ i # ys) k"
    73   show "\<And>j. is_path' r j xs i \<Longrightarrow> is_path' r j (xs @ i # ys) k"
    81   proof (induct xs)
    74   proof (induct xs)
    82     case (Nil j)
    75     case (Nil j)
    83     hence "r j i = T" by simp
    76     then have "r j i = T" by simp
    84     with pys show ?case by simp
    77     with pys show ?case by simp
    85   next
    78   next
    86     case (Cons z zs j)
    79     case (Cons z zs j)
    87     hence jzr: "r j z = T" by simp
    80     then have jzr: "r j z = T" by simp
    88     from Cons have pzs: "is_path' r z zs i" by simp
    81     from Cons have pzs: "is_path' r z zs i" by simp
    89     show ?case
    82     show ?case
    90       by simp (rule conjI jzr Cons pzs)+
    83       by simp (rule conjI jzr Cons pzs)+
    91   qed
    84   qed
    92 qed
    85 qed
    93 
    86 
    94 theorem lemma3:
    87 theorem lemma3:
    95   "\<And>p q. is_path r p i j i \<Longrightarrow> is_path r q i i k \<Longrightarrow>
    88   "\<And>p q. is_path r p i j i \<Longrightarrow> is_path r q i i k \<Longrightarrow>
    96    is_path r (conc p q) (Suc i) j k"
    89     is_path r (conc p q) (Suc i) j k"
    97   apply (unfold is_path_def conc_def)
    90   apply (unfold is_path_def conc_def)
    98   apply (simp cong add: conj_cong add: split_paired_all)
    91   apply (simp cong add: conj_cong add: split_paired_all)
    99   apply (erule conjE)+
    92   apply (erule conjE)+
   100   apply (rule conjI)
    93   apply (rule conjI)
   101   apply (erule list_all_lemma)
    94   apply (erule list_all_lemma)
   106   apply (rule is_path'_conc)
    99   apply (rule is_path'_conc)
   107   apply assumption+
   100   apply assumption+
   108   done
   101   done
   109 
   102 
   110 theorem lemma5:
   103 theorem lemma5:
   111   "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> ~ is_path r p i j k \<Longrightarrow>
   104   "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> \<not> is_path r p i j k \<Longrightarrow>
   112    (\<exists>q. is_path r q i j i) \<and> (\<exists>q'. is_path r q' i i k)"
   105     (\<exists>q. is_path r q i j i) \<and> (\<exists>q'. is_path r q' i i k)"
   113 proof (simp cong add: conj_cong add: split_paired_all is_path_def, (erule conjE)+)
   106 proof (simp cong add: conj_cong add: split_paired_all is_path_def, (erule conjE)+)
   114   fix xs
   107   fix xs
   115   assume asms:
   108   assume asms:
   116     "list_all (\<lambda>x. x < Suc i) xs"
   109     "list_all (\<lambda>x. x < Suc i) xs"
   117     "is_path' r j xs k"
   110     "is_path' r j xs k"
   122     have "\<And>j. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow>
   115     have "\<And>j. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow>
   123       \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow>
   116       \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow>
   124     \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r j ys i" (is "PROP ?ih xs")
   117     \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r j ys i" (is "PROP ?ih xs")
   125     proof (induct xs)
   118     proof (induct xs)
   126       case Nil
   119       case Nil
   127       thus ?case by simp
   120       then show ?case by simp
   128     next
   121     next
   129       case (Cons a as j)
   122       case (Cons a as j)
   130       show ?case
   123       show ?case
   131       proof (cases "a=i")
   124       proof (cases "a=i")
   132         case True
   125         case True
   133         show ?thesis
   126         show ?thesis
   134         proof
   127         proof
   135           from True and Cons have "r j i = T" by simp
   128           from True and Cons have "r j i = T" by simp
   136           thus "list_all (\<lambda>x. x < i) [] \<and> is_path' r j [] i" by simp
   129           then show "list_all (\<lambda>x. x < i) [] \<and> is_path' r j [] i" by simp
   137         qed
   130         qed
   138       next
   131       next
   139         case False
   132         case False
   140         have "PROP ?ih as" by (rule Cons)
   133         have "PROP ?ih as" by (rule Cons)
   141         then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r a ys i"
   134         then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r a ys i"
   155     have "\<And>k. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow>
   148     have "\<And>k. list_all (\<lambda>x. x < Suc i) xs \<Longrightarrow> is_path' r j xs k \<Longrightarrow>
   156       \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow>
   149       \<not> list_all (\<lambda>x. x < i) xs \<Longrightarrow>
   157       \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys k" (is "PROP ?ih xs")
   150       \<exists>ys. list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys k" (is "PROP ?ih xs")
   158     proof (induct xs rule: rev_induct)
   151     proof (induct xs rule: rev_induct)
   159       case Nil
   152       case Nil
   160       thus ?case by simp
   153       then show ?case by simp
   161     next
   154     next
   162       case (snoc a as k)
   155       case (snoc a as k)
   163       show ?case
   156       show ?case
   164       proof (cases "a=i")
   157       proof (cases "a=i")
   165         case True
   158         case True
   166         show ?thesis
   159         show ?thesis
   167         proof
   160         proof
   168           from True and snoc have "r i k = T" by simp
   161           from True and snoc have "r i k = T" by simp
   169           thus "list_all (\<lambda>x. x < i) [] \<and> is_path' r i [] k" by simp
   162           then show "list_all (\<lambda>x. x < i) [] \<and> is_path' r i [] k" by simp
   170         qed
   163         qed
   171       next
   164       next
   172         case False
   165         case False
   173         have "PROP ?ih as" by (rule snoc)
   166         have "PROP ?ih as" by (rule snoc)
   174         then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys a"
   167         then obtain ys where ys: "list_all (\<lambda>x. x < i) ys \<and> is_path' r i ys a"
   189   qed
   182   qed
   190 qed
   183 qed
   191 
   184 
   192 theorem lemma5':
   185 theorem lemma5':
   193   "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> \<not> is_path r p i j k \<Longrightarrow>
   186   "\<And>p. is_path r p (Suc i) j k \<Longrightarrow> \<not> is_path r p i j k \<Longrightarrow>
   194    \<not> (\<forall>q. \<not> is_path r q i j i) \<and> \<not> (\<forall>q'. \<not> is_path r q' i i k)"
   187     \<not> (\<forall>q. \<not> is_path r q i j i) \<and> \<not> (\<forall>q'. \<not> is_path r q' i i k)"
   195   by (iprover dest: lemma5)
   188   by (iprover dest: lemma5)
   196 
   189 
   197 theorem warshall: 
   190 theorem warshall: "\<And>j k. \<not> (\<exists>p. is_path r p i j k) \<or> (\<exists>p. is_path r p i j k)"
   198   "\<And>j k. \<not> (\<exists>p. is_path r p i j k) \<or> (\<exists>p. is_path r p i j k)"
       
   199 proof (induct i)
   191 proof (induct i)
   200   case (0 j k)
   192   case (0 j k)
   201   show ?case
   193   show ?case
   202   proof (cases "r j k")
   194   proof (cases "r j k")
   203     assume "r j k = T"
   195     assume "r j k = T"
   204     hence "is_path r (j, [], k) 0 j k"
   196     then have "is_path r (j, [], k) 0 j k"
   205       by (simp add: is_path_def)
   197       by (simp add: is_path_def)
   206     hence "\<exists>p. is_path r p 0 j k" ..
   198     then have "\<exists>p. is_path r p 0 j k" ..
   207     thus ?thesis ..
   199     then show ?thesis ..
   208   next
   200   next
   209     assume "r j k = F"
   201     assume "r j k = F"
   210     hence "r j k ~= T" by simp
   202     then have "r j k \<noteq> T" by simp
   211     hence "\<not> (\<exists>p. is_path r p 0 j k)"
   203     then have "\<not> (\<exists>p. is_path r p 0 j k)"
   212       by (iprover dest: lemma2)
   204       by (iprover dest: lemma2)
   213     thus ?thesis ..
   205     then show ?thesis ..
   214   qed
   206   qed
   215 next
   207 next
   216   case (Suc i j k)
   208   case (Suc i j k)
   217   thus ?case
   209   then show ?case
   218   proof
   210   proof
   219     assume h1: "\<not> (\<exists>p. is_path r p i j k)"
   211     assume h1: "\<not> (\<exists>p. is_path r p i j k)"
   220     from Suc show ?case
   212     from Suc show ?case
   221     proof
   213     proof
   222       assume "\<not> (\<exists>p. is_path r p i j i)"
   214       assume "\<not> (\<exists>p. is_path r p i j i)"
   223       with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)"
   215       with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)"
   224         by (iprover dest: lemma5')
   216         by (iprover dest: lemma5')
   225       thus ?case ..
   217       then show ?case ..
   226     next
   218     next
   227       assume "\<exists>p. is_path r p i j i"
   219       assume "\<exists>p. is_path r p i j i"
   228       then obtain p where h2: "is_path r p i j i" ..
   220       then obtain p where h2: "is_path r p i j i" ..
   229       from Suc show ?case
   221       from Suc show ?case
   230       proof
   222       proof
   231         assume "\<not> (\<exists>p. is_path r p i i k)"
   223         assume "\<not> (\<exists>p. is_path r p i i k)"
   232         with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)"
   224         with h1 have "\<not> (\<exists>p. is_path r p (Suc i) j k)"
   233           by (iprover dest: lemma5')
   225           by (iprover dest: lemma5')
   234         thus ?case ..
   226         then show ?case ..
   235       next
   227       next
   236         assume "\<exists>q. is_path r q i i k"
   228         assume "\<exists>q. is_path r q i i k"
   237         then obtain q where "is_path r q i i k" ..
   229         then obtain q where "is_path r q i i k" ..
   238         with h2 have "is_path r (conc p q) (Suc i) j k" 
   230         with h2 have "is_path r (conc p q) (Suc i) j k" 
   239           by (rule lemma3)
   231           by (rule lemma3)
   240         hence "\<exists>pq. is_path r pq (Suc i) j k" ..
   232         then have "\<exists>pq. is_path r pq (Suc i) j k" ..
   241         thus ?case ..
   233         then show ?case ..
   242       qed
   234       qed
   243     qed
   235     qed
   244   next
   236   next
   245     assume "\<exists>p. is_path r p i j k"
   237     assume "\<exists>p. is_path r p i j k"
   246     hence "\<exists>p. is_path r p (Suc i) j k"
   238     then have "\<exists>p. is_path r p (Suc i) j k"
   247       by (iprover intro: lemma1)
   239       by (iprover intro: lemma1)
   248     thus ?case ..
   240     then show ?case ..
   249   qed
   241   qed
   250 qed
   242 qed
   251 
   243 
   252 extract warshall
   244 extract warshall
   253 
   245