ProgTutorial/Essential.thy
changeset 441 520127b708e6
parent 440 a0b280dd4bc7
child 446 4c32349b9875
equal deleted inserted replaced
440:a0b280dd4bc7 441:520127b708e6
     1 theory Essential
     1 theory Essential
     2 imports Base FirstSteps
     2 imports Base First_Steps
     3 begin
     3 begin
     4 
     4 
     5 (*<*)
     5 (*<*)
     6 setup{*
     6 setup{*
     7 open_file_with_prelude 
     7 open_file_with_prelude 
     8   "Essential_Code.thy"
     8   "Essential_Code.thy"
     9   ["theory Essential", "imports Base FirstSteps", "begin"]
     9   ["theory Essential", "imports Base First_Steps", "begin"]
    10 *}
    10 *}
    11 (*>*)
    11 (*>*)
    12 
    12 
    13 
    13 
    14 chapter {* Isabelle Essentials *}
    14 chapter {* Isabelle Essentials *}
    82 "let
    82 "let
    83   val v1 = Var ((\"x\", 3), @{typ bool})
    83   val v1 = Var ((\"x\", 3), @{typ bool})
    84   val v2 = Var ((\"x1\", 3), @{typ bool})
    84   val v2 = Var ((\"x1\", 3), @{typ bool})
    85   val v3 = Free (\"x\", @{typ bool})
    85   val v3 = Free (\"x\", @{typ bool})
    86 in
    86 in
    87   string_of_terms @{context} [v1, v2, v3]
    87   pretty_terms @{context} [v1, v2, v3]
    88   |> tracing
    88   |> pwriteln
    89 end"
    89 end"
    90 "?x3, ?x1.3, x"}
    90 "?x3, ?x1.3, x"}
    91 
    91 
    92   When constructing terms, you are usually concerned with free variables (as
    92   When constructing terms, you are usually concerned with free variables (as
    93   mentioned earlier, you cannot construct schematic variables using the
    93   mentioned earlier, you cannot construct schematic variables using the
   116 
   116 
   117   @{ML_response_fake [display,gray] 
   117   @{ML_response_fake [display,gray] 
   118 "let
   118 "let
   119   val omega = Free (\"x\", @{typ \"nat \<Rightarrow> nat\"}) $ Free (\"x\", @{typ nat})
   119   val omega = Free (\"x\", @{typ \"nat \<Rightarrow> nat\"}) $ Free (\"x\", @{typ nat})
   120 in 
   120 in 
   121   tracing (string_of_term @{context} omega)
   121   pwriteln (pretty_term @{context} omega)
   122 end"
   122 end"
   123   "x x"}
   123   "x x"}
   124   
   124   
   125   Sometimes the internal representation of terms can be surprisingly different
   125   Sometimes the internal representation of terms can be surprisingly different
   126   from what you see at the user-level, because the layers of
   126   from what you see at the user-level, because the layers of
   421   @{ML_response_fake [display, gray, linenos]
   421   @{ML_response_fake [display, gray, linenos]
   422   "let
   422   "let
   423   val (vrs, trm) = strip_alls @{term \"\<forall>x y. x = (y::bool)\"}
   423   val (vrs, trm) = strip_alls @{term \"\<forall>x y. x = (y::bool)\"}
   424 in 
   424 in 
   425   subst_bounds (rev vrs, trm) 
   425   subst_bounds (rev vrs, trm) 
   426   |> string_of_term @{context}
   426   |> pretty_term @{context}
   427   |> tracing
   427   |> pwriteln
   428 end"
   428 end"
   429   "x = y"}
   429   "x = y"}
   430 
   430 
   431   Note that in Line 4 we had to reverse the list of variables that @{ML
   431   Note that in Line 4 we had to reverse the list of variables that @{ML
   432   strip_alls} returned. The reason is that the head of the list the function
   432   strip_alls} returned. The reason is that the head of the list the function
   455 
   455 
   456 @{ML_response_fake [gray,display]
   456 @{ML_response_fake [gray,display]
   457 "let
   457 "let
   458   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
   458   val eq = HOLogic.mk_eq (@{term \"True\"}, @{term \"False\"})
   459 in
   459 in
   460   string_of_term @{context} eq
   460   eq |> pretty_term @{context}
   461   |> tracing
   461      |> pwriteln
   462 end"
   462 end"
   463   "True = False"}
   463   "True = False"}
   464 
   464 
   465   \begin{readmore}
   465   \begin{readmore}
   466   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file
   466   There are many functions in @{ML_file "Pure/term.ML"}, @{ML_file
   711   \begin{figure}[t]
   711   \begin{figure}[t]
   712   \begin{minipage}{\textwidth}
   712   \begin{minipage}{\textwidth}
   713   \begin{isabelle}*}
   713   \begin{isabelle}*}
   714 ML{*fun pretty_helper aux env =
   714 ML{*fun pretty_helper aux env =
   715   env |> Vartab.dest  
   715   env |> Vartab.dest  
   716       |> map ((fn (s1, s2) => s1 ^ " := " ^ s2) o aux) 
   716       |> map ((fn (s1, s2) => Pretty.block [s1, Pretty.str ";=", s2]) o aux) 
   717       |> commas 
   717       |> Pretty.commas 
   718       |> enclose "[" "]" 
   718       |> Pretty.enum "" "[" "]" 
   719       |> tracing
   719       |> pwriteln
   720 
   720 
   721 fun pretty_tyenv ctxt tyenv =
   721 fun pretty_tyenv ctxt tyenv =
   722 let
   722 let
   723   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   723   fun get_typs (v, (s, T)) = (TVar (v, s), T)
   724   val print = pairself (Syntax.string_of_typ ctxt)
   724   val print = pairself (pretty_typ ctxt)
   725 in 
   725 in 
   726   pretty_helper (print o get_typs) tyenv
   726   pretty_helper (print o get_typs) tyenv
   727 end*}
   727 end*}
   728 text_raw {*
   728 text_raw {*
   729   \end{isabelle}
   729   \end{isabelle}
   899 *}
   899 *}
   900 
   900 
   901 ML{*fun pretty_env ctxt env =
   901 ML{*fun pretty_env ctxt env =
   902 let
   902 let
   903   fun get_trms (v, (T, t)) = (Var (v, T), t) 
   903   fun get_trms (v, (T, t)) = (Var (v, T), t) 
   904   val print = pairself (string_of_term ctxt)
   904   val print = pairself (pretty_term ctxt)
   905 in
   905 in
   906   pretty_helper (print o get_trms) env 
   906   pretty_helper (print o get_trms) env 
   907 end*}
   907 end*}
   908 
   908 
   909 text {*
   909 text {*
   940   @{ML_response_fake [display, gray]
   940   @{ML_response_fake [display, gray]
   941   "let
   941   "let
   942   val trm = @{term_pat \"(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y\"}
   942   val trm = @{term_pat \"(?X::(nat\<Rightarrow>nat\<Rightarrow>nat)\<Rightarrow>bool) ?Y\"}
   943 in
   943 in
   944   Envir.subst_term (Vartab.empty, fo_env) trm
   944   Envir.subst_term (Vartab.empty, fo_env) trm
   945   |> string_of_term @{context}
   945   |> pretty_term @{context}
   946   |> tracing
   946   |> pwriteln
   947 end"
   947 end"
   948   "P (\<lambda>a b. Q b a)"}
   948   "P (\<lambda>a b. Q b a)"}
   949 
   949 
   950   First-order matching is useful for matching against applications and
   950   First-order matching is useful for matching against applications and
   951   variables. It can also deal with abstractions and a limited form of
   951   variables. It can also deal with abstractions and a limited form of
  1022   "Envir.term_env"} pulls out the term environment from the result record. The
  1022   "Envir.term_env"} pulls out the term environment from the result record. The
  1023   corresponding function for type environment is @{ML_ind
  1023   corresponding function for type environment is @{ML_ind
  1024   "Envir.type_env"}. An assumption of this function is that the terms to be
  1024   "Envir.type_env"}. An assumption of this function is that the terms to be
  1025   unified have already the same type. In case of failure, the exceptions that
  1025   unified have already the same type. In case of failure, the exceptions that
  1026   are raised are either @{text Pattern}, @{text MATCH} or @{text Unif}.
  1026   are raised are either @{text Pattern}, @{text MATCH} or @{text Unif}.
  1027 *}
       
  1028 
       
  1029 (*
       
  1030 ML {*
       
  1031   fun patunif_in_emptyenv (t, u) =
       
  1032     let
       
  1033       val init = Envir.empty 0;
       
  1034       val env = Pattern.unify @{theory} (t, u) init;
       
  1035     in
       
  1036       (env |> Envir.term_env |> Vartab.dest,
       
  1037        env |> Envir.type_env |> Vartab.dest)
       
  1038     end
       
  1039 *}
       
  1040 
       
  1041 text {*
       
  1042 @{ML_response [display, gray]
       
  1043  "val t1 = @{term_pat \"(% x y. ?f y x)\"};
       
  1044  val u1 = @{term_pat \"z::bool\"};
       
  1045    (* type conflict isnt noticed *)
       
  1046  patunif_in_emptyenv (t1, u1);"
       
  1047  "check missing"
       
  1048 *}
       
  1049 @{ML_response [display, gray] 
       
  1050  "val t2 = @{term_pat \"(% y. ?f y)\"} |> Term.strip_abs_body;
       
  1051  val u2 = @{term_pat \"z::bool\"};
       
  1052    (* fails because of loose bounds *)
       
  1053  (* patunif_in_emptyenv (t2, u2) *)"
       
  1054  "check missing"
       
  1055 *}
       
  1056 @{ML_response [display, gray]
       
  1057  "val t3 = @{term_pat \"(% y. plu (?f y) (% x. g x))\"};
       
  1058  val u3 = @{term_pat \"(% y. plu y (% x. g x))\"};
       
  1059    (* eta redexe im term egal, hidden polym wird inst *)
       
  1060  patunif_in_emptyenv (t3, u3)"
       
  1061  "check missing"
       
  1062 *}
       
  1063 @{ML_response [display, gray] 
       
  1064  "val t4 = @{term_pat \"(% y. plu (?f y) ((% x. g x) k))\"};
       
  1065  val u4 = @{term_pat \"(% y. plu y ((% x. g x) k))\"};
       
  1066    (* beta redexe are largely ignored, hidden polymorphism is instantiated *)
       
  1067  patunif_in_emptyenv (t4, u4)"
       
  1068  "check missing"
       
  1069 *}
       
  1070 @{ML_response [display, gray]
       
  1071  "val t5 = @{term_pat \"(% y. plu ((% x. ?f) y) ((% x. g x) k))\"};
       
  1072  val u5 = @{term_pat \"(% y. plu y ((% x. g x) k))\"};
       
  1073    (* fails: can't have beta redexes which seperate a var from its arguments *)
       
  1074  (* patunif_in_emptyenv (t5, u5) *)"
       
  1075 *}
       
  1076 
       
  1077 @{ML_response [display, gray] 
       
  1078  "val t6 = @{term_pat \"(% x y. ?f x y) a b\"};
       
  1079  val u6 = @{term_pat \"c\"};
       
  1080  (* Pattern.pattern assumes argument is beta-normal *)
       
  1081  Pattern.pattern t6; 
       
  1082    (* fails: can't have beta redexes which seperate a var from its arguments,
       
  1083        otherwise this would be general unification for general a,b,c *)
       
  1084  (* patunif_in_emptyenv (t6, u6) *)"
       
  1085 *}
       
  1086 @{ML_response [display, gray]
       
  1087  "val t7 = @{term_pat \"(% y. plu ((% x. ?f x) y) ((% x. g x) k))\"};
       
  1088  val u7 = @{term_pat \"(% y. plu y ((% x. g x) k))\"};
       
  1089    (* eta redexe die Pattern trennen brauchen nicht normalisiert sein *)
       
  1090  patunif_in_emptyenv (t7, u7)"
       
  1091 *}
       
  1092 @{ML_response [display, gray] 
       
  1093  "val t8 = @{term_pat \"(% y. ?f y)\"};
       
  1094  val u8 = @{term_pat \"(% y. y ?f)\"};
       
  1095    (* variables of the same name are identified *)
       
  1096  (* patunif_in_emptyenv (t8, u8) *)"
       
  1097 *}
       
  1098 
       
  1099 @{ML_response [display, gray]
       
  1100  "val t9 = @{term_pat \"(% y. ?f y)\"};
       
  1101  val u9 = @{term_pat \"(% y. ?f y)\"};
       
  1102    (* trivial solutions are empty and don't contain ?f = ?f etc *)
       
  1103  patunif_in_emptyenv (t9, u9)"
       
  1104 *}
       
  1105 @{ML_response [display, gray] 
       
  1106  "val t10 = @{term_pat \"(% y. (% x. ?f x) y)\"};
       
  1107  val u10 = @{term_pat \"(% y. ?f y)\"};
       
  1108    (* trivial solutions are empty and don't contain ?f = ?f etc *)
       
  1109  patunif_in_emptyenv (t10, u10)"
       
  1110 *}
       
  1111 @{ML_response [display, gray]
       
  1112  "val t11 = @{term_pat \"(% z. ?f z)\"};
       
  1113  val u11 = @{term_pat \"(% z. k (?f z))\"};
       
  1114    (* fails: occurs check *)
       
  1115  (* patunif_in_emptyenv (t11, u11) *)"
       
  1116 *}
       
  1117 @{ML_response [display, gray]
       
  1118  "val t12 = @{term_pat \"(% z. ?f z)\"};
       
  1119  val u12 = @{term_pat \"?g a\"};
       
  1120    (* fails: *both* terme have to be higher-order patterns *)
       
  1121  (* patunif_in_emptyenv (t12, u12) *)"
       
  1122 *}
       
  1123 *}
       
  1124 *)
       
  1125 
       
  1126 text {*
       
  1127 
  1027 
  1128   As mentioned before, unrestricted higher-order unification, respectively
  1028   As mentioned before, unrestricted higher-order unification, respectively
  1129   unrestricted higher-order matching, is in general undecidable and might also
  1029   unrestricted higher-order matching, is in general undecidable and might also
  1130   not posses a single most general solution. Therefore Isabelle implements the
  1030   not posses a single most general solution. Therefore Isabelle implements the
  1131   unification function @{ML_ind unifiers in Unify} so that it returns a lazy
  1031   unification function @{ML_ind unifiers in Unify} so that it returns a lazy
  1717   @{ML_response_fake [display,gray]
  1617   @{ML_response_fake [display,gray]
  1718   "let
  1618   "let
  1719   val eq = @{thm True_def}
  1619   val eq = @{thm True_def}
  1720 in
  1620 in
  1721   (Thm.lhs_of eq, Thm.rhs_of eq) 
  1621   (Thm.lhs_of eq, Thm.rhs_of eq) 
  1722   |> pairself (string_of_cterm @{context})
  1622   |> pairself (Pretty.string_of o (pretty_cterm @{context}))
  1723 end"
  1623 end"
  1724   "(True, (\<lambda>x. x) = (\<lambda>x. x))"}
  1624   "(True, (\<lambda>x. x) = (\<lambda>x. x))"}
  1725 
  1625 
  1726   Other function produce terms that can be pattern-matched. 
  1626   Other function produce terms that can be pattern-matched. 
  1727   Suppose the following two theorems.
  1627   Suppose the following two theorems.
  1736 
  1636 
  1737  @{ML_response_fake [display,gray]
  1637  @{ML_response_fake [display,gray]
  1738 "let
  1638 "let
  1739   val ctxt = @{context}
  1639   val ctxt = @{context}
  1740   fun prems_and_concl thm =
  1640   fun prems_and_concl thm =
  1741      [\"Premises: \"   ^ (string_of_terms ctxt (Thm.prems_of thm))] @ 
  1641      [[Pretty.str \"Premises:\", pretty_terms ctxt (Thm.prems_of thm)], 
  1742      [\"Conclusion: \" ^ (string_of_term ctxt (Thm.concl_of thm))]
  1642       [Pretty.str \"Conclusion:\", pretty_term ctxt (Thm.concl_of thm)]]
  1743      |> cat_lines
  1643      |> map Pretty.block
  1744      |> tracing
  1644      |> Pretty.chunks
       
  1645      |> pwriteln
  1745 in
  1646 in
  1746   prems_and_concl @{thm foo_test1};
  1647   prems_and_concl @{thm foo_test1};
  1747   prems_and_concl @{thm foo_test2}
  1648   prems_and_concl @{thm foo_test2}
  1748 end"
  1649 end"
  1749 "Premises: ?A, ?B
  1650 "Premises: ?A, ?B