ProgTutorial/Essential.thy
changeset 448 957f69b9b7df
parent 446 4c32349b9875
child 449 f952f2679a11
equal deleted inserted replaced
447:d21cea8e0bcf 448:957f69b9b7df
   148   usually invisible @{text "Trueprop"}-coercions whenever necessary. 
   148   usually invisible @{text "Trueprop"}-coercions whenever necessary. 
   149   Consider for example the pairs
   149   Consider for example the pairs
   150 
   150 
   151 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   151 @{ML_response [display,gray] "(@{term \"P x\"}, @{prop \"P x\"})" 
   152 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   152 "(Free (\"P\", \<dots>) $ Free (\"x\", \<dots>),
   153  Const (\"Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   153  Const (\"HOL.Trueprop\", \<dots>) $ (Free (\"P\", \<dots>) $ Free (\"x\", \<dots>)))"}
   154  
   154 
   155   where a coercion is inserted in the second component and 
   155   where a coercion is inserted in the second component and 
   156 
   156 
   157   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   157   @{ML_response [display,gray] "(@{term \"P x \<Longrightarrow> Q x\"}, @{prop \"P x \<Longrightarrow> Q x\"})" 
   158   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, 
   158   "(Const (\"==>\", \<dots>) $ \<dots> $ \<dots>, 
   159  Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   159  Const (\"==>\", \<dots>) $ \<dots> $ \<dots>)"}
   225 text {*
   225 text {*
   226   Now the type bool is printed out in full detail.
   226   Now the type bool is printed out in full detail.
   227 
   227 
   228   @{ML_response [display,gray]
   228   @{ML_response [display,gray]
   229   "@{typ \"bool\"}"
   229   "@{typ \"bool\"}"
   230   "Type (\"bool\", [])"}
   230   "Type (\"HOL.bool\", [])"}
   231 
   231 
   232   When printing out a list-type
   232   When printing out a list-type
   233   
   233   
   234   @{ML_response [display,gray]
   234   @{ML_response [display,gray]
   235   "@{typ \"'a list\"}"
   235   "@{typ \"'a list\"}"
   242   theories @{text "HOL"} and @{text "Nat"}, respectively, they are 
   242   theories @{text "HOL"} and @{text "Nat"}, respectively, they are 
   243   still represented by their simple name.
   243   still represented by their simple name.
   244 
   244 
   245    @{ML_response [display,gray]
   245    @{ML_response [display,gray]
   246   "@{typ \"bool \<Rightarrow> nat\"}"
   246   "@{typ \"bool \<Rightarrow> nat\"}"
   247   "Type (\"fun\", [Type (\"bool\", []), Type (\"Nat.nat\", [])])"}
   247   "Type (\"fun\", [Type (\"HOL.bool\", []), Type (\"Nat.nat\", [])])"}
   248 
   248 
   249   We can restore the usual behaviour of Isabelle's pretty printer
   249   We can restore the usual behaviour of Isabelle's pretty printer
   250   with the code
   250   with the code
   251 *}
   251 *}
   252 
   252 
   494   fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for 
   494   fixes the type of the constant @{term "All"} to be @{typ "('a \<Rightarrow> bool) \<Rightarrow> bool"} for 
   495   an arbitrary, but fixed type @{typ "'a"}. A properly working alternative 
   495   an arbitrary, but fixed type @{typ "'a"}. A properly working alternative 
   496   for this function is
   496   for this function is
   497 *}
   497 *}
   498 
   498 
   499 ML{*fun is_all (Const ("All", _) $ _) = true
   499 ML{*fun is_all (Const ("HOL.All", _) $ _) = true
   500   | is_all _ = false*}
   500   | is_all _ = false*}
   501 
   501 
   502 text {* 
   502 text {* 
   503   because now
   503   because now
   504 
   504 
   505 @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
   505   @{ML_response [display,gray] "is_all @{term \"\<forall>x::nat. P x\"}" "true"}
   506 
   506 
   507   matches correctly (the first wildcard in the pattern matches any type and the
   507   matches correctly (the first wildcard in the pattern matches any type and the
   508   second any term).
   508   second any term).
   509 
   509 
   510   However there is still a problem: consider the similar function that
   510   However there is still a problem: consider the similar function that
   719   \begin{figure}[t]
   719   \begin{figure}[t]
   720   \begin{minipage}{\textwidth}
   720   \begin{minipage}{\textwidth}
   721   \begin{isabelle}*}
   721   \begin{isabelle}*}
   722 ML{*fun pretty_helper aux env =
   722 ML{*fun pretty_helper aux env =
   723   env |> Vartab.dest  
   723   env |> Vartab.dest  
   724       |> map ((fn (s1, s2) => Pretty.block [s1, Pretty.str ";=", s2]) o aux) 
   724       |> map aux
   725       |> Pretty.commas 
   725       |> map (fn (s1, s2) => Pretty.block [s1, Pretty.str " := ", s2]) 
   726       |> Pretty.enum "" "[" "]" 
   726       |> Pretty.enum "," "[" "]" 
   727       |> pwriteln
   727       |> pwriteln
   728 
   728 
   729 fun pretty_tyenv ctxt tyenv =
   729 fun pretty_tyenv ctxt tyenv =
   730 let
   730 let
   731   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   731   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   976 *}
   976 *}
   977 
   977 
   978 text {*
   978 text {*
   979   Unification of abstractions is more thoroughly studied in the context of
   979   Unification of abstractions is more thoroughly studied in the context of
   980   higher-order pattern unification and higher-order pattern matching.  A
   980   higher-order pattern unification and higher-order pattern matching.  A
   981   \emph{\index*{pattern}} is a well-formed beta-normal term in which the arguments to
   981   \emph{\index*{pattern}} is a well-formed term in which the arguments to
   982   every schematic variable are distinct bounds.
   982   every schematic variable are distinct bounds.
   983   In particular this excludes terms where a
   983   In particular this excludes terms where a
   984   schematic variable is an argument of another one and where a schematic
   984   schematic variable is an argument of another one and where a schematic
   985   variable is applied twice with the same bound variable. The function
   985   variable is applied twice with the same bound variable. The function
   986   @{ML_ind pattern in Pattern} in the structure @{ML_struct Pattern} tests
   986   @{ML_ind pattern in Pattern} in the structure @{ML_struct Pattern} tests
  1739   "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"}
  1739   "\<forall>P list. P [] \<longrightarrow> (\<forall>a list. P list \<longrightarrow> P (a # list)) \<longrightarrow> P list"}
  1740 
  1740 
  1741   Theorems can also be produced from terms by giving an explicit proof. 
  1741   Theorems can also be produced from terms by giving an explicit proof. 
  1742   One way to achieve this is by using the function @{ML_ind prove in Goal}
  1742   One way to achieve this is by using the function @{ML_ind prove in Goal}
  1743   in the structure @{ML_struct Goal}. For example below we use this function
  1743   in the structure @{ML_struct Goal}. For example below we use this function
  1744   to prove the term @{term "P \<Longrightarrow> P"}.\footnote{\bf FIXME: What about @{ML_ind prove_internal in Goal}?}
  1744   to prove the term @{term "P \<Longrightarrow> P"}.
  1745   
  1745   
  1746   @{ML_response_fake [display,gray]
  1746   @{ML_response_fake [display,gray]
  1747   "let
  1747   "let
  1748   val trm = @{term \"P \<Longrightarrow> P::bool\"}
  1748   val trm = @{term \"P \<Longrightarrow> P::bool\"}
  1749   val tac = K (atac 1)
  1749   val tac = K (atac 1)
  1752 end"
  1752 end"
  1753   "?P \<Longrightarrow> ?P"}
  1753   "?P \<Longrightarrow> ?P"}
  1754 
  1754 
  1755   This function takes first a context and second a list of strings. This list
  1755   This function takes first a context and second a list of strings. This list
  1756   specifies which variables should be turned into schematic variables once the term
  1756   specifies which variables should be turned into schematic variables once the term
  1757   is proved.  The fourth argument is the term to be proved. The fifth is a
  1757   is proved (in this case only @{text "\"P\""}).  The fourth argument is the term to be 
  1758   corresponding proof given in form of a tactic (we explain tactics in
  1758   proved. The fifth is a corresponding proof given in form of a tactic (we explain 
  1759   Chapter~\ref{chp:tactical}). In the code above, the tactic proves the theorem
  1759   tactics in Chapter~\ref{chp:tactical}). In the code above, the tactic proves the 
  1760   by assumption. As before this code will produce a theorem, but the theorem
  1760   theorem by assumption. 
  1761   is not yet stored in the theorem database. 
  1761 
  1762 
  1762   There is also the possibility of proving multiple goals at the same time
       
  1763   using the function @{ML_ind prove_multi in Goal}. For this let us define the
       
  1764   following three helper functions.
       
  1765 *}
       
  1766 
       
  1767 ML{*fun rep_goals i = replicate i @{prop "f x = f x"}
       
  1768 fun rep_tacs i = replicate i (rtac @{thm refl})
       
  1769 
       
  1770 fun multi_test ctxt i =
       
  1771   Goal.prove_multi ctxt ["f", "x"] [] (rep_goals i) 
       
  1772     (K ((Goal.conjunction_tac THEN' RANGE (rep_tacs i)) 1))*}
       
  1773 
       
  1774 text {*
       
  1775   With them we can now produce three theorem instances of the 
       
  1776   proposition.
       
  1777 
       
  1778   @{ML_response_fake [display, gray]
       
  1779   "multi_test @{context} 3"
       
  1780   "[\"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\", \"?f ?x = ?f ?x\"]"}
       
  1781 
       
  1782   However you should be careful with @{ML prove_multi in Goal} and very
       
  1783   large goals. If you increase the counter in the code above to @{text 3000}, 
       
  1784   you will notice that takes approximately ten(!) times longer than
       
  1785   using @{ML map} and @{ML prove in Goal}.
       
  1786 *}
       
  1787   
       
  1788 ML{*let 
       
  1789   fun test_prove ctxt thm =
       
  1790     Goal.prove ctxt ["P", "x"] [] thm (K (rtac @{thm refl} 1))
       
  1791 in
       
  1792   map (test_prove @{context}) (rep_goals 3000)
       
  1793 end*}
       
  1794 
       
  1795 text {*
  1763   While the LCF-approach of going through interfaces ensures soundness in Isabelle, there
  1796   While the LCF-approach of going through interfaces ensures soundness in Isabelle, there
  1764   is the function @{ML_ind make_thm in Skip_Proof} in the structure 
  1797   is the function @{ML_ind make_thm in Skip_Proof} in the structure 
  1765   @{ML_struct Skip_Proof} that allows us to turn any proposition into a theorem.
  1798   @{ML_struct Skip_Proof} that allows us to turn any proposition into a theorem.
  1766   Potentially making the system unsound.  This is sometimes useful for developing 
  1799   Potentially making the system unsound.  This is sometimes useful for developing 
  1767   purposes, or when explicit proof construction should be omitted due to performace 
  1800   purposes, or when explicit proof construction should be omitted due to performace