diff -r be23597e81db -r f875a25aa72d ProgTutorial/Advanced.thy --- a/ProgTutorial/Advanced.thy Fri May 17 07:29:51 2019 +0200 +++ b/ProgTutorial/Advanced.thy Fri May 17 10:38:01 2019 +0200 @@ -132,14 +132,13 @@ \begin{isabelle} \begin{graybox} - \isacommand{setup}~\\\ @{ML -"fn thy => + \isacommand{setup}~\\\ @{ML \fn thy => let - val bar_const = ((@{binding \"BAR\"}, @{typ \"nat\"}), NoSyn) + val bar_const = ((@{binding "BAR"}, @{typ "nat"}), NoSyn) val (_, thy') = Sign.declare_const @{context} bar_const thy in thy -end"}~\\\\isanewline +end\}~\\\\isanewline \> ERROR: "Stale theory encountered"\ \end{graybox} \end{isabelle} @@ -215,14 +214,14 @@ \begin{isabelle} \begin{graybox} - @{ML "let - val trm = @{term \"(x, y, z, w)\"} + @{ML \let + val trm = @{term "(x, y, z, w)"} in pwriteln (Pretty.chunks [ pretty_term ctxt0 trm, pretty_term ctxt1 trm, pretty_term ctxt2 trm ]) -end"}\\ +end\}\\ \setlength{\fboxsep}{0mm} \>\~\(\\colorbox{gray!5}{\raisebox{0mm}[3mm][1mm]{\x\}}\,\~% \colorbox{gray!5}{\raisebox{0mm}[3mm][1mm]{\y\}}\,\~% @@ -241,9 +240,8 @@ The term we are printing is in all three cases the same---a tuple containing - four free variables. As you can see, however, in case of @{ML "ctxt0"} all - variables are highlighted indicating a problem, while in case of @{ML - "ctxt1"} \x\ and \y\ are printed as normal (blue) free + four free variables. As you can see, however, in case of @{ML \ctxt0\} all + variables are highlighted indicating a problem, while in case of @{ML \ctxt1\} \x\ and \y\ are printed as normal (blue) free variables, but not \z\ and \w\. In the last case all variables are printed as expected. The point of this example is that the context contains the information which variables are fixed, and designates all other @@ -253,18 +251,18 @@ fixing a variable twice @{ML_matchresult_fake [gray, display] - "@{context} -|> Variable.add_fixes [\"x\", \"x\"]" - "ERROR: Duplicate fixed variable(s): \"x\""} + \@{context} +|> Variable.add_fixes ["x", "x"]\ + \ERROR: Duplicate fixed variable(s): "x"\} More importantly it also allows us to easily create fresh names for fixed variables. For this you have to use the function @{ML_ind variant_fixes in Variable} from the structure @{ML_structure Variable}. @{ML_matchresult_fake [gray, display] - "@{context} -|> Variable.variant_fixes [\"y\", \"y\", \"z\"]" - "([\"y\", \"ya\", \"z\"], ...)"} + \@{context} +|> Variable.variant_fixes ["y", "y", "z"]\ + \(["y", "ya", "z"], ...)\} Now a fresh variant for the second occurence of \y\ is created avoiding any clash. In this way we can also create fresh free variables @@ -274,16 +272,16 @@ string @{text [quotes] "x"} (Lines 6 and 7). @{ML_matchresult_fake [display, gray, linenos] - "let + \let val ctxt0 = @{context} - val (_, ctxt1) = Variable.add_fixes [\"x\"] ctxt0 - val frees = replicate 2 (\"x\", @{typ nat}) + val (_, ctxt1) = Variable.add_fixes ["x"] ctxt0 + val frees = replicate 2 ("x", @{typ nat}) in (Variable.variant_frees ctxt0 [] frees, Variable.variant_frees ctxt1 [] frees) -end" - "([(\"x\", \"nat\"), (\"xa\", \"nat\")], - [(\"xa\", \"nat\"), (\"xb\", \"nat\")])"} +end\ + \([("x", "nat"), ("xa", "nat")], + [("xa", "nat"), ("xb", "nat")])\} As you can see, if we create the fresh variables with the context \ctxt0\, then we obtain \x\ and \xa\; but in \ctxt1\ we obtain \xa\ @@ -294,13 +292,13 @@ function @{ML_ind declare_term in Variable} from the structure @{ML_structure Variable}. @{ML_matchresult_fake [gray, display] - "let - val ctxt1 = Variable.declare_term @{term \"(x, xa)\"} @{context} - val frees = replicate 2 (\"x\", @{typ nat}) + \let + val ctxt1 = Variable.declare_term @{term "(x, xa)"} @{context} + val frees = replicate 2 ("x", @{typ nat}) in Variable.variant_frees ctxt1 [] frees -end" - "[(\"xb\", \"nat\"), (\"xc\", \"nat\")]"} +end\ + \[("xb", "nat"), ("xc", "nat")]\} The result is \xb\ and \xc\ for the names of the fresh variables, since \x\ and \xa\ occur in the term we declared. @@ -310,12 +308,12 @@ \begin{isabelle} \begin{graybox} - @{ML "let - val trm = @{term \"P x y z\"} + @{ML \let + val trm = @{term "P x y z"} val ctxt1 = Variable.declare_term trm @{context} in pwriteln (pretty_term ctxt1 trm) -end"}\\ +end\}\\ \setlength{\fboxsep}{0mm} \>\~\colorbox{gray!5}{\raisebox{0mm}[3mm][1mm]{\P\}}~% \colorbox{gray!5}{\raisebox{0mm}[3mm][1mm]{\x\}}~% @@ -330,14 +328,14 @@ @{ML_structure Syntax}. Consider the following code: @{ML_matchresult_fake [gray, display] - "let + \let val ctxt0 = @{context} - val ctxt1 = Variable.declare_term @{term \"x::nat\"} ctxt0 + val ctxt1 = Variable.declare_term @{term "x::nat"} ctxt0 in - (Syntax.read_term ctxt0 \"x\", - Syntax.read_term ctxt1 \"x\") -end" - "(Free (\"x\", \"'a\"), Free (\"x\", \"nat\"))"} + (Syntax.read_term ctxt0 "x", + Syntax.read_term ctxt1 "x") +end\ + \(Free ("x", "'a"), Free ("x", "nat"))\} Parsing the string in the context \ctxt0\ results in a free variable with a default polymorphic type, but in case of \ctxt1\ we obtain a @@ -346,14 +344,14 @@ is made, as the next example illustrates. @{ML_matchresult_fake [gray, display] - "let - val ctxt1 = Variable.declare_term @{term \"x::nat\"} @{context} - val ctxt2 = Variable.declare_term @{term \"x::int\"} ctxt1 + \let + val ctxt1 = Variable.declare_term @{term "x::nat"} @{context} + val ctxt2 = Variable.declare_term @{term "x::int"} ctxt1 in - (Syntax.read_term ctxt1 \"x\", - Syntax.read_term ctxt2 \"x\") -end" - "(Free (\"x\", \"nat\"), Free (\"x\", \"int\"))"} + (Syntax.read_term ctxt1 "x", + Syntax.read_term ctxt2 "x") +end\ + \(Free ("x", "nat"), Free ("x", "int"))\} The most useful feature of contexts is that one can export, or transfer, terms and theorems between them. We show this first for terms. @@ -361,15 +359,15 @@ \begin{isabelle} \begin{graybox} \begin{linenos} - @{ML "let + @{ML \let val ctxt0 = @{context} - val (_, ctxt1) = Variable.add_fixes [\"x\", \"y\", \"z\"] ctxt0 - val foo_trm = @{term \"P x y z\"} + val (_, ctxt1) = Variable.add_fixes ["x", "y", "z"] ctxt0 + val foo_trm = @{term "P x y z"} in singleton (Variable.export_terms ctxt1 ctxt0) foo_trm |> pretty_term ctxt0 |> pwriteln -end"} +end\} \end{linenos} \setlength{\fboxsep}{0mm} \>\~\colorbox{gray!5}{\raisebox{0mm}[3mm][1mm]{\P\}}~% @@ -401,15 +399,15 @@ whether it is actually provable). @{ML_matchresult_fake [display, gray] - "let + \let val thy = @{theory} val ctxt0 = @{context} - val (_, ctxt1) = Variable.add_fixes [\"P\", \"x\", \"y\", \"z\"] ctxt0 - val foo_thm = Skip_Proof.make_thm thy @{prop \"P x y z x y z\"} + val (_, ctxt1) = Variable.add_fixes ["P", "x", "y", "z"] ctxt0 + val foo_thm = Skip_Proof.make_thm thy @{prop "P x y z x y z"} in singleton (Proof_Context.export ctxt1 ctxt0) foo_thm -end" - "?P ?x ?y ?z ?x ?y ?z"} +end\ + \?P ?x ?y ?z ?x ?y ?z\} Since we fixed all variables in \ctxt1\, in the exported result all of them are schematic. The great point of contexts is @@ -419,14 +417,14 @@ @{ML_structure Assumption}. Consider the following code. @{ML_matchresult_fake [display, gray, linenos] - "let + \let val ctxt0 = @{context} - val ([eq], ctxt1) = Assumption.add_assumes [@{cprop \"x \ y\"}] ctxt0 + val ([eq], ctxt1) = Assumption.add_assumes [@{cprop "x \ y"}] ctxt0 val eq' = Thm.symmetric eq in Assumption.export false ctxt1 ctxt0 eq' -end" - "x \ y \ y \ x"} +end\ + \x \ y \ y \ x\} The function @{ML_ind add_assumes in Assumption} from the structure @{ML_structure Assumption} adds the assumption \mbox{\x \ y\} @@ -451,16 +449,16 @@ in the following example. @{ML_matchresult_fake [display, gray] - "let + \let val ctxt0 = @{context} val ((fvs, [eq]), ctxt1) = ctxt0 - |> Variable.add_fixes [\"x\", \"y\"] - ||>> Assumption.add_assumes [@{cprop \"x \ y\"}] + |> Variable.add_fixes ["x", "y"] + ||>> Assumption.add_assumes [@{cprop "x \ y"}] val eq' = Thm.symmetric eq in Proof_Context.export ctxt1 ctxt0 [eq'] -end" - "[?x \ ?y \ ?y \ ?x]"} +end\ + \[?x \ ?y \ ?y \ ?x]\} \ @@ -515,7 +513,7 @@ @{ML_type "Proof.context"}, although not every proof context constitutes a valid local theory. - @{ML "Context.>> o Context.map_theory"} + @{ML \Context.>> o Context.map_theory\} @{ML_ind "Local_Theory.declaration"} A similar command is \isacommand{local\_setup}, which expects a function @@ -590,8 +588,8 @@ antiquotation \@{binding \}\. For example @{ML_matchresult [display,gray] - "@{binding \"name\"}" - "name"} + \@{binding "name"}\ + \name\} An example where a qualified name is needed is the function @{ML_ind define in Local_Theory}. This function is used below to define @@ -634,7 +632,7 @@ Occasionally you have to calculate what the ``base'' name of a given constant is. For this you can use the function @{ML_ind Long_Name.base_name}. For example: - @{ML_matchresult [display,gray] "Long_Name.base_name \"List.list.Nil\"" "\"Nil\""} + @{ML_matchresult [display,gray] \Long_Name.base_name "List.list.Nil"\ \"Nil"\} \begin{readmore} Functions about naming are implemented in @{ML_file "Pure/General/name_space.ML"};