Re: [isabelle-dev] adhoc overloading: ugly output
Hi Christian, Thanks for pointing this out. While yours is a valid observation, it seems that observing abbrev_mode is not enough to obtain nicer output, i.e., when using fun uncheck ctxt ts = - if Config.get ctxt show_variants orelse exists (is_none o try Term.type_of) ts then ts + if Proof_Context.abbrev_mode ctxt orelse +Config.get ctxt show_variants orelse +exists (not o can Term.type_of) ts then ts else map (insert_overloaded ctxt) ts; instead of the above, the output of term xs ≤⇩♯ ys stays the same as in my initial post, namely Foo.le_sharp ♯ xs ys i.e. the problem is still open, although the formal gap between abbreviations and ad-hoc overloading got closer. I have this issue on my agenda, though not prioritized. The abbreviation machinery is a delicate issue, and so is the (un)check machinery: it is not compositional, and additions are supposed to work smoothly with all pre-existing plugins here. In similar situations in the past I always did some phyiscal experiments to get some clues what to examine next. The idea is to plug in an (un)checker which does nothing than diagnostic output. Feeding this with terms can give valid inspirations. A tedious issue, of course. Cheers, Florian -- PGP available: http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_informatik_tu_muenchen_de signature.asc Description: OpenPGP digital signature ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading: ugly output
Hi Chris, I've pushed it to the testboard (and will push it to the repository in case of success): http://isabelle.in.tum.de/testboard/Isabelle/rev/0d7de4d99eac Cheers, Dmitriy On 28.01.2015 09:55, Christian Sternagel wrote: It is amazing how easy some things get when a wizard is looking over your shoulder (thanks Florian!). It turns out that adhoc overloading (which is in essence very similar to abbreviations) did not observe some conventions that are followed by the abbreviation command. By peeking into the sources - even without understanding much of it ;) - it can be seen that the flag abbrev_mode is checked for abbreviations. By doing the same inside adhoc_overloading the ugly output I presented earlier, turned into beautiful symbols. Could one of the developers be so kind to apply the attached (mq) patch (after testing it of course) ;) ? cheers chris On 01/16/2015 02:40 PM, Christian Sternagel wrote: Here is a related thread https://www.mail-archive.com/isabelle-dev@mailbroy.informatik.tu-muenchen.de/msg04950.html which was originated by myself ;) (how embarassing). cheers chris On 01/16/2015 02:35 PM, Christian Sternagel wrote: Dear all, in Isabelle2014 as well as c7f6f01ede15 I noticed that the output when using adhoc overloading together with abbreviations is not optimal (maybe this was already discovered before but I forgot about it). Now, it turns out that the same issue (at least superficially it's the same, but maybe caused by different reasons) arises also for definitions in local theory contexts (or are those the same as mere abbreviations?). Let me illustrate what I'm talking about by the following example: theory Foo imports Main ~~/src/Tools/Adhoc_Overloading begin consts SHARP :: 'a ⇒ 'b (♯) context fixes shp :: 'a ⇒ 'a begin adhoc_overloading SHARP shp definition le_sharp (infix ≤⇩♯ 50) where xs ≤⇩♯ ys ≡ list_all2 (λx y. y = x ∨ y = ♯ x) xs ys term xs ≤⇩♯ ys text ‹ Result in @{term Foo.le_sharp ♯ xs ys} instead of more desirable @{term xs ≤⇩♯ ys}. (The same happens when we turn the above definition into an abbreviation.) › end text ‹ In the global theory this also happens, but only for abbreviations, not for definitions. › definition shp = id adhoc_overloading SHARP shp definition le_sharp' (infix ≤⇩♯ 50) where xs ≤⇩♯ ys ≡ list_all2 (λx y. y = x ∨ y = ♯ x) xs ys term xs ≤⇩♯ ys end Unfortunately, at the moment I do not have time to look into adhoc overloading myself, but let this thread be a reminder. If anybody else can provide explanations/comments/solutions, please go ahead! cheers chris ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading: ugly output
It is amazing how easy some things get when a wizard is looking over your shoulder (thanks Florian!). It turns out that adhoc overloading (which is in essence very similar to abbreviations) did not observe some conventions that are followed by the abbreviation command. By peeking into the sources - even without understanding much of it ;) - it can be seen that the flag abbrev_mode is checked for abbreviations. By doing the same inside adhoc_overloading the ugly output I presented earlier, turned into beautiful symbols. Could one of the developers be so kind to apply the attached (mq) patch (after testing it of course) ;) ? cheers chris On 01/16/2015 02:40 PM, Christian Sternagel wrote: Here is a related thread https://www.mail-archive.com/isabelle-dev@mailbroy.informatik.tu-muenchen.de/msg04950.html which was originated by myself ;) (how embarassing). cheers chris On 01/16/2015 02:35 PM, Christian Sternagel wrote: Dear all, in Isabelle2014 as well as c7f6f01ede15 I noticed that the output when using adhoc overloading together with abbreviations is not optimal (maybe this was already discovered before but I forgot about it). Now, it turns out that the same issue (at least superficially it's the same, but maybe caused by different reasons) arises also for definitions in local theory contexts (or are those the same as mere abbreviations?). Let me illustrate what I'm talking about by the following example: theory Foo imports Main ~~/src/Tools/Adhoc_Overloading begin consts SHARP :: 'a ⇒ 'b (♯) context fixes shp :: 'a ⇒ 'a begin adhoc_overloading SHARP shp definition le_sharp (infix ≤⇩♯ 50) where xs ≤⇩♯ ys ≡ list_all2 (λx y. y = x ∨ y = ♯ x) xs ys term xs ≤⇩♯ ys text ‹ Result in @{term Foo.le_sharp ♯ xs ys} instead of more desirable @{term xs ≤⇩♯ ys}. (The same happens when we turn the above definition into an abbreviation.) › end text ‹ In the global theory this also happens, but only for abbreviations, not for definitions. › definition shp = id adhoc_overloading SHARP shp definition le_sharp' (infix ≤⇩♯ 50) where xs ≤⇩♯ ys ≡ list_all2 (λx y. y = x ∨ y = ♯ x) xs ys term xs ≤⇩♯ ys end Unfortunately, at the moment I do not have time to look into adhoc overloading myself, but let this thread be a reminder. If anybody else can provide explanations/comments/solutions, please go ahead! cheers chris # HG changeset patch # Parent 4427f04fca57ea90f7fd8dbc271ac29a9268ec75 adhoc overloading must follow the same conventions as abbreviations diff -r 4427f04fca57 -r fbefd978e72d src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.MLSun Jan 25 22:11:06 2015 +0100 +++ b/src/Tools/adhoc_overloading.MLTue Jan 27 13:59:16 2015 +0100 @@ -179,7 +179,9 @@ map (fn t = Term.map_aterms (insert_variants ctxt t) t); fun uncheck ctxt ts = - if Config.get ctxt show_variants orelse exists (is_none o try Term.type_of) ts then ts + if Proof_Context.abbrev_mode ctxt orelse +Config.get ctxt show_variants orelse +exists (can Term.type_of) ts then ts else map (insert_overloaded ctxt) ts; fun reject_unresolved ctxt = ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading: ugly output
fun uncheck ctxt ts = - if Config.get ctxt show_variants orelse exists (is_none o try Term.type_of) ts then ts + if Proof_Context.abbrev_mode ctxt orelse +Config.get ctxt show_variants orelse +exists (can Term.type_of) ts then ts else map (insert_overloaded ctxt) ts; Nb. is_none o try f -- not o can f This got swapped in this patch and is maybe the reason for failing to solve the problem. Cheers, Florian -- PGP available: http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_informatik_tu_muenchen_de signature.asc Description: OpenPGP digital signature ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading: order inserting overloaded constant
On Sat, 1 Feb 2014, Christian Sternagel wrote: So my idea was to instead use top-down rewriting (i.e., first replace maximal subterms that fit a given pattern). This is what Pattern.rewrite_term_top does, right? So after replacing rewrite_term by rewrite_term_top, I get the expected results. Now my question. Can anybody think of a reason why rewrite_term_top would not be generally preferable over rewrite_term inside of insert_overloaded? This is an old story. Printing usually works better top-down, e.g. see good old 'translations' with their yo-yo strategy. When 'abbreviation' was introduced, there was Pattern.rewrite_term, but not Pattern.rewrite_term_top yet, so there was no other way. I kept telling Stefan Berghofer about that omission until he made an laternative version in 2010: see 6e45e4c94751, 5d2fe4e09354 (with typical tell-nothing log entries). So in analogy, the same will probably work for adhoc_overloading as well, without going through all the reasoning again. If not, could one of the devs incorporate this tiny change please? OK, I will try this out. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading: order inserting overloaded constant
On Sat, 1 Feb 2014, Makarius wrote: If not, could one of the devs incorporate this tiny change please? OK, I will try this out. See now: changeset: 55237:1e341728bae9 user:wenzelm date:Sat Feb 01 20:46:19 2014 +0100 files: src/Tools/adhoc_overloading.ML description: prefer top-down rewriting for output (i.e. uncheck), in accordance to term abbreviations (see 5d2fe4e09354) and AST translations; Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Tue, 6 Aug 2013, Christian Sternagel wrote: Please find attached a file containing all my changes. OK, this is now at Isabelle/73e32ed924b3 and a few changes before. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Fri, 2 Aug 2013, Christian Sternagel wrote: On 08/02/2013 12:04 AM, Makarius wrote: On Wed, 17 Jul 2013, Christian Sternagel wrote: in case anybody finds localized ad-hoc overloading useful. Quite often it is just a matter to tell users about the existence of such useful tools. Do you feel like making an example theory, e.g. src/HOL/ex/Adhoc_Overloading_Examples.thy or a short entry for the isar-ref manual? E.g. somewhere here http://isabelle.in.tum.de/repos/isabelle/annotate/122416054a9c/src/Doc/IsarRef/HOL_Specific.thy I gave both a try. Please find the resulting changesets (via hg export) attached (I also squeezed in some unrelated changes: spell-checking, tuning of error messages. I hope that is okay). The tuning etc. is fine (it looks like done with care). What is missing in the commit is your new file src/HOL/ex/Adhoc_Overloading_Examples.thy Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
Dear Makarius, actually even more is missing, since I was not able to properly use hg export (I am used to hg bundle which exports *all* changesets that are only local, whereas for hg export I have to give all revisions that should be exported explicitly). Sorry for that. Please find attached a file containing all my changes. cheers chris On 08/06/2013 03:34 AM, Makarius wrote: On Fri, 2 Aug 2013, Christian Sternagel wrote: On 08/02/2013 12:04 AM, Makarius wrote: On Wed, 17 Jul 2013, Christian Sternagel wrote: in case anybody finds localized ad-hoc overloading useful. Quite often it is just a matter to tell users about the existence of such useful tools. Do you feel like making an example theory, e.g. src/HOL/ex/Adhoc_Overloading_Examples.thy or a short entry for the isar-ref manual? E.g. somewhere here http://isabelle.in.tum.de/repos/isabelle/annotate/122416054a9c/src/Doc/IsarRef/HOL_Specific.thy I gave both a try. Please find the resulting changesets (via hg export) attached (I also squeezed in some unrelated changes: spell-checking, tuning of error messages. I hope that is okay). The tuning etc. is fine (it looks like done with care). What is missing in the commit is your new file src/HOL/ex/Adhoc_Overloading_Examples.thy Makarius # HG changeset patch # User Christian Sternagel # Date 1375413062 -32400 # Fri Aug 02 12:11:02 2013 +0900 # Node ID 8173d8eb92c59711abede67ca2c035ed3e02beb6 # Parent cc425a7dc9adbcc95b7c6ed124466384e087275e tuned formatting of error message diff --git a/src/Tools/adhoc_overloading.ML b/src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.ML +++ b/src/Tools/adhoc_overloading.ML @@ -41,7 +41,7 @@ in term :: quote (Syntax.string_of_term ctxt' t) :: (if null instances then no instances else multiple instances:) :: -map (Syntax.string_of_term ctxt') instances) +map (Markup.markup Markup.item o Syntax.string_of_term ctxt') instances) | error end; # HG changeset patch # User Christian Sternagel # Date 1375425679 -32400 # Fri Aug 02 15:41:19 2013 +0900 # Node ID f3ab98f28d70c18a919b23fbd6a5daffba212251 # Parent 8173d8eb92c59711abede67ca2c035ed3e02beb6 use uniform spelling of adhoc diff --git a/src/Tools/Adhoc_Overloading.thy b/src/Tools/Adhoc_Overloading.thy --- a/src/Tools/Adhoc_Overloading.thy +++ b/src/Tools/Adhoc_Overloading.thy @@ -2,7 +2,7 @@ Author: Christian Sternagel, University of Innsbruck *) -header {* Ad-hoc overloading of constants based on their types *} +header {* Adhoc overloading of constants based on their types *} theory Adhoc_Overloading imports Pure diff --git a/src/Tools/adhoc_overloading.ML b/src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.ML +++ b/src/Tools/adhoc_overloading.ML @@ -1,7 +1,7 @@ (* Author: Alexander Krauss, TU Muenchen Author: Christian Sternagel, University of Innsbruck -Ad-hoc overloading of constants based on their types. +Adhoc overloading of constants based on their types. *) signature ADHOC_OVERLOADING = @@ -227,12 +227,12 @@ val _ = Outer_Syntax.local_theory @{command_spec adhoc_overloading} -add ad-hoc overloading for constants / fixed variables +add adhoc overloading for constants / fixed variables (Parse.and_list1 (Parse.const -- Scan.repeat Parse.term) adhoc_overloading_cmd true); val _ = Outer_Syntax.local_theory @{command_spec no_adhoc_overloading} -add ad-hoc overloading for constants / fixed variables +add adhoc overloading for constants / fixed variables (Parse.and_list1 (Parse.const -- Scan.repeat Parse.term) adhoc_overloading_cmd false); end; # HG changeset patch # User Christian Sternagel # Date 1375425721 -32400 # Fri Aug 02 15:42:01 2013 +0900 # Node ID 5e53d4373e38de46b1f0358aeca06ecd8fbb4bdb # Parent f3ab98f28d70c18a919b23fbd6a5daffba212251 added examples of adhoc overloading diff --git a/src/HOL/ex/Adhoc_Overloading_Examples.thy b/src/HOL/ex/Adhoc_Overloading_Examples.thy new file mode 100644 --- /dev/null +++ b/src/HOL/ex/Adhoc_Overloading_Examples.thy @@ -0,0 +1,250 @@ +(* Title: HOL/ex/Adhoc_Overloading_Examples.thy +Author: Christian Sternagel +*) + +header {* Ad Hoc Overloading *} + +theory Adhoc_Overloading_Examples +imports + Main + ~~/src/Tools/Adhoc_Overloading + ~~/src/HOL/Library/Infinite_Set +begin + +text {*Adhoc overloading allows to overload a constant depending on +its type. Typically this involves to introduce an uninterpreted +constant (used for input and output) and then add some variants (used +internally).*} + +subsection {* Plain Ad Hoc Overloading *} + +text {*Consider the type of first-order terms.*} +datatype ('a, 'b) term = + Var 'b | + Fun 'a ('a, 'b) term list + +text {*The set of variables of a term might be computed as follows.*} +fun term_vars :: ('a, 'b) term \Rightarrow 'b set where + term_vars (Var x) = {x} | + term_vars (Fun f ts) = \Unionset (map term_vars ts) + +text {*However, also
Re: [isabelle-dev] adhoc overloading
On 08/02/2013 12:04 AM, Makarius wrote: On Wed, 17 Jul 2013, Christian Sternagel wrote: in case anybody finds localized ad-hoc overloading useful. Quite often it is just a matter to tell users about the existence of such useful tools. Do you feel like making an example theory, e.g. src/HOL/ex/Adhoc_Overloading_Examples.thy or a short entry for the isar-ref manual? E.g. somewhere here http://isabelle.in.tum.de/repos/isabelle/annotate/122416054a9c/src/Doc/IsarRef/HOL_Specific.thy I gave both a try. Please find the resulting changesets (via hg export) attached (I also squeezed in some unrelated changes: spell-checking, tuning of error messages. I hope that is okay). cheers chris # HG changeset patch # User Christian Sternagel # Date 1375425767 -32400 # Fri Aug 02 15:42:47 2013 +0900 # Node ID a854ff7d191ae0735664632516e3274a1e7bd2f7 # Parent 5e53d4373e38de46b1f0358aeca06ecd8fbb4bdb some documentation for adhoc overloading; spell-checked; diff -r 5e53d4373e38 -r a854ff7d191a src/Doc/IsarRef/HOL_Specific.thy --- a/src/Doc/IsarRef/HOL_Specific.thy Fri Aug 02 15:42:01 2013 +0900 +++ b/src/Doc/IsarRef/HOL_Specific.thy Fri Aug 02 15:42:47 2013 +0900 @@ -1,5 +1,5 @@ theory HOL_Specific -imports Base Main ~~/src/HOL/Library/Old_Recdef +imports Base Main ~~/src/HOL/Library/Old_Recdef ~~/src/Tools/Adhoc_Overloading begin chapter {* Higher-Order Logic *} @@ -588,7 +588,7 @@ There are no fixed syntactic restrictions on the body of the function, but the induced functional must be provably monotonic - wrt.\ the underlying order. The monotonicitity proof is performed + wrt.\ the underlying order. The monotonicity proof is performed internally, and the definition is rejected when it fails. The proof can be influenced by declaring hints using the @{attribute (HOL) partial_function_mono} attribute. @@ -622,7 +622,7 @@ @{const partial_function_definitions} appropriately. \item @{attribute (HOL) partial_function_mono} declares rules for - use in the internal monononicity proofs of partial function + use in the internal monotonicity proofs of partial function definitions. \end{description} @@ -1288,7 +1288,7 @@ morphisms} specification provides alternative names. @{command (HOL) quotient_type} requires the user to prove that the relation is an equivalence relation (predicate @{text equivp}), unless the - user specifies explicitely @{text partial} in which case the + user specifies explicitly @{text partial} in which case the obligation is @{text part_equivp}. A quotient defined with @{text partial} is weaker in the sense that less things can be proved automatically. @@ -1318,7 +1318,7 @@ and @{method (HOL) descending} continues in the same way as @{method (HOL) lifting} does. @{method (HOL) descending} tries to solve the arising regularization, injection and cleaning -subgoals with the analoguous method @{method (HOL) +subgoals with the analogous method @{method (HOL) descending_setup} which leaves the four unsolved subgoals. \item @{method (HOL) partiality_descending} finds the regularized @@ -1416,6 +1416,46 @@ problem, one should use @{command (HOL) ax_specification}. *} +section {* Adhoc overloading of constants *} + +text {* + \begin{tabular}{rcll} + @{command_def adhoc_overloading} : @{text local_theory \rightarrow local_theory} \\ + @{command_def no_adhoc_overloading} : @{text local_theory \rightarrow local_theory} \\ + @{attribute_def show_variants} : @{text attribute} default @{text false} \\ + \end{tabular} + + \medskip + + Adhoc overloading allows to overload a constant depending on + its type. Typically this involves the introduction of an + uninterpreted constant (used for input and output) and the addition + of some variants (used internally). For examples see + @{file ~~/src/HOL/ex/Adhoc_Overloading_Examples.thy} and + @{file ~~/src/HOL/Library/Monad_Syntax.thy}. + + @{rail +(@@{command adhoc_overloading} | @@{command no_adhoc_overloading}) +(@{syntax nameref} (@{syntax term} + ) + @'and') + } + + \begin{description} + + \item @{command adhoc_overloading}~@{text c v\^isub1 ... v\^isubn} + associates variants with an existing constant. + + \item @{command no_adhoc_overloading} is similar to + @{command adhoc_overloading}, but removes the specified variants + from the present context. + + \item @{attribute show_variants} controls printing of variants + of overloaded constants. If enabled, the internally used variants + are printed instead of their respective overloaded constants. This + is occasionally useful to check whether the system agrees with a + user's expectations about derived variants. + + \end{description} +*} chapter {* Proof tools *} @@ -1553,7 +1593,7 @@ equations in the code generator. The option @{text no_code} of the command @{command (HOL) setup_lifting} can turn off that behavior and causes that code
Re: [isabelle-dev] adhoc overloading
On Wed, 17 Jul 2013, Christian Sternagel wrote: in case anybody finds localized ad-hoc overloading useful. Quite often it is just a matter to tell users about the existence of such useful tools. Do you feel like making an example theory, e.g. src/HOL/ex/Adhoc_Overloading_Examples.thy or a short entry for the isar-ref manual? E.g. somewhere here http://isabelle.in.tum.de/repos/isabelle/annotate/122416054a9c/src/Doc/IsarRef/HOL_Specific.thy Strictly speaking it is probably not HOL specific, but re-use of the Pure type language within the object-logic is somehow part of the specific Isabelle/HOL tradition. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Wednesday, July 17, 2013 at 13:43:34 (+0900), Christian Sternagel wrote: @all: please let me know, in case anybody finds localized ad-hoc overloading useful. An aside: I'm currently using localized ad-hoc overloading for a port of Nominal2's permutation type, where I use locales instead of type classes. The reason is that, if I understand correctly, when using Nominal datatypes I loose code generation... is that still true for Nominal2? For an existing term datatype of IsaFoR I want to have notions of supports/set of variables and freshness. That is my intended application of the above mentioned port, to be found at https://bitbucket.org/csternagel/permutations Yes. I think nobody has figured out what code should be generated for the *quotients* that nominal datatypes are in general. Best wishes, Christian On 07/13/2013 12:00 AM, Makarius wrote: On Fri, 12 Jul 2013, Christian Sternagel wrote: The patches should be ready to push (for your convenience I attached them once more; the attached patches are the same as from my previous e-mail). Btw, I generated the patches against Isabelle 8afb396d9178 and AFP 908304753f7d (but I guess this information is also included in the patches ;)). This is now Isabelle/e0ff1625e96d and AFP/74746c992248. Since you did not provide formal changesets, only diffs, I invented some log messages on the spot. (Normally I use the hg export / hg import pair for small-scale patch-flow, but hg import was happy importing plain diffs like this.) I added Isabelle/fee0db8cf60d to keep the generated Proof General keyword tables in sync. This is now trivial with the isabelle update_keywords tool in its fully static version. (In the past there was always a full build required before applying it, or a good guess which sessions contribute to the keyword tables.) Makarius -- # HG changeset patch # User Christian Sternagel # Date 1374031154 -32400 # Wed Jul 17 12:19:14 2013 +0900 # Node ID bfd42890e3b7bd6c475460023bcddb8723f19247 # Parent c16f35e5a5aa3861a5f94dc1230d8859363de879 refactoring diff -r c16f35e5a5aa -r bfd42890e3b7 src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.ML Tue Jul 16 23:34:33 2013 +0200 +++ b/src/Tools/adhoc_overloading.ML Wed Jul 17 12:19:14 2013 +0900 @@ -137,9 +137,12 @@ handle Type.TUNIFY = NONE end; +fun get_instances ctxt (c, T) = + Same.function (get_variants ctxt) c + | map_filter (unifiable_with (Proof_Context.theory_of ctxt) T); + fun insert_variants_same ctxt t (Const (c, T)) = - (case map_filter (unifiable_with (Proof_Context.theory_of ctxt) T) - (Same.function (get_variants ctxt) c) of + (case get_instances ctxt (c, T) of [] = unresolved_overloading_error ctxt (c, T) t no instances | [variant] = variant | _ = raise Same.SAME) # HG changeset patch # User Christian Sternagel # Date 1374032519 -32400 # Wed Jul 17 12:41:59 2013 +0900 # Node ID 2903a6e128fafc25085171880d1b63eb1cc4be02 # Parent bfd42890e3b7bd6c475460023bcddb8723f19247 show variants in error messages; more precise error messages (give witnesses for multiple instances) diff -r bfd42890e3b7 -r 2903a6e128fa src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.ML Wed Jul 17 12:19:14 2013 +0900 +++ b/src/Tools/adhoc_overloading.ML Wed Jul 17 12:41:59 2013 +0900 @@ -32,10 +32,18 @@ fun not_overloaded_error oconst = error (Constant ^ quote oconst ^ is not declared as overloaded); -fun unresolved_overloading_error ctxt (c, T) t reason = - error (Unresolved overloading of ^ quote c ^ :: ^ -quote (Syntax.string_of_typ ctxt T) ^ in ^ -quote (Syntax.string_of_term ctxt t) ^ ( ^ reason ^ )); +fun unresolved_overloading_error ctxt (c, T) t instances = + let val ctxt' = Config.put show_variants true ctxt + in +cat_lines ( + Unresolved overloading of constant :: + quote c ^ :: ^ quote (Syntax.string_of_typ ctxt' T) :: + in term :: + quote (Syntax.string_of_term ctxt' t) :: + (if null instances then no instances else multiple instances:) :: +map (Syntax.string_of_term ctxt') instances) +| error + end; (* generic data *) @@ -143,7 +151,7 @@ fun insert_variants_same ctxt t (Const (c, T)) = (case get_instances ctxt (c, T) of -[] = unresolved_overloading_error ctxt (c, T) t no instances +[] = unresolved_overloading_error ctxt (c, T) t [] | [variant] = variant | _ = raise Same.SAME) | insert_variants_same _ _ _ = raise Same.SAME; @@ -176,7 +184,7 @@ fun check_unresolved t = (case filter (is_overloaded ctxt o fst) (Term.add_consts t []) of [] = ()
Re: [isabelle-dev] adhoc overloading
On Wed, 17 Jul 2013, Christian Sternagel wrote: Here are two follow-up patches (this time generated by hg export) that improve error messages for multiple instances (actually showing the existing instances to the user). I have imported them as 72cda5eb5a39 and 1e13b2515e2b. BTW, the log message format allows several items, but these should be put on a separate line each (with terminator as you've had already). This format is meant for speed-reading of changelogs, e.g. see this view: http://isabelle.in.tum.de/repos/isabelle/log/52688 (It also shows that many people have already forgotten that.) In the old times log entries were extremely short. In recent years the art of squezing additional reasoning and explanations into each item-line has further developed, but too much blah blah is not good. Anyway, I still need to read through your present implementation to give a few further hints, e.g. concerning the question about type inference in a local context that emerged recently. It should all work, if the proper context is used. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
Dear all, please find attached patches for localizing src/Tools/Adhoc_Overloading.thy. It should work like the previous version in the non-local case, besides a more convenient interface, i.e., instead of setup {* Adhoc_Overloading.add_overloaded @{const_name foo} # Adhoc_Overloading.add_variant @{const_name foo} @{const_name bar} *} it is now adhoc_overloading foo bar where bar may be an arbitrary term (not just a constant). For removing ad-hoc overloading there is the command no_adhoc_overloading. I tested the local case only on toy examples. Comments are welcome. cheers chris On 07/11/2013 04:36 PM, Christian Sternagel wrote: Dear all, here is an update to my previous message. Corresponding patches are attached (tested with `isabelle build_doc -pa` and `isabelle afp_build -A`). Some comments: 1) Variants are stored as terms but where all types are mapped to dummyT (which makes it easier to check for a given term, whether it is a variant of an overloaded constant). 2) In the table that maps overloaded constants to variants in addition to the dummy-typed variant also a type is included (where all free type variables are replaced by schematic ones). 3) As stated by Dmitriy in the type unification thread the current solution does not work for localization (but the corresponding change is trivial, I'm just avoiding it for the moment, since without localization I have to work with a thy, which is inconvenient to turn into a ctxt as required by Variable.polymorphic). cheers chris On 07/10/2013 04:38 PM, Christian Sternagel wrote: First of all, thanks for all the useful answers and sorry for my late reply (I visited a conference and had some holidays ;)). As Alexander suggested, I first tried to modify the existing adhoc_overloading.ML in such a way that variants may be arbitrary terms. Please find the results of my attempt attached (the new adhoc_overloading.ML as well as a patch-file). Now I will investigate further localization. Any comments are welcome. cheers chris On 06/02/2013 08:55 AM, Alexander Krauss wrote: Hi Chris, I'm currently (as of changeset e6433b34364b) investigating whether it would be possible to allow adhoc overloading (implemented in ~~/src/Tools/adhoc_overloading.ML) inside local contexts. Nice! For completeness find my current adhoc_overloading.ML attached Apart from the various formalities pointed out by Makarius, here is another concern, which relates to Florian's earlier question about how local you want to be... Currently, Adhoc_Overloading replaces constants with other constants, which makes it global-only. Your current version tries to deal with Frees similarly, it's not just that. Recall the example you gave previously: consts FOO :: ... (some syntax) setup {* Adhoc_Overloading.add_overloaded @{const_name FOO} *} locale foo = fixes foo :: ... assumes ... begin local_setup {* Adhoc_Overloading.add_variant @{const_name FOO} @{term foo} *} Now consider the following interpretation: interpretation foo some term proof Now, some term should become a variant of FOO, so at least the variant side of the overloading relation must be an arbitrary term. With your current code, the overloading would only survive interpretations where foo happens to be mapped to a constant. So, I guess that the overloaded constants should remain constants, since they are just syntactic anyway. It seems that localizing those would be rather artificial. But the variants must be properly localized and subject to the morphism. As a step towards proper localization, you could start with the global code, and first generalize it to accept arbitrary terms as variants. Note that this touches in particular the uncheck phase, which can no longer use Term_Subst.map_aterms_same (or Term.map_aterms), since it becomes general rewriting. One must resort to the more general Pattern.rewrite_term here. When all this is working again, the actual localization is then a mere formality, of which you have already discovered the ingredients. Makarius wrote: * Same.function seems to be a let-over from the version by Alex Krauss. He had that once in his function package, copied from somewhere else (probably old code of mine). No, it has nothing to do with the function package, which never used any Same stuff. It just arose rather naturally from the requirement to return NONE when nothing changes... So it was not meant as an optimization. There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only So should I manually check the result for equality, or does the framework do this for me? Alex diff -r 908304753f7d thys/JinjaThreads/Framework/FWState.thy --- a/thys/JinjaThreads/Framework/FWState.thy Thu Jul 11 13:37:41 2013 +0200 +++ b/thys/JinjaThreads/Framework/FWState.thy Fri Jul 12 19:47:05 2013 +0900 @@ -188,15 +188,9 @@ _ta_lock la l == CONST
Re: [isabelle-dev] adhoc overloading
On Fri, 12 Jul 2013, Christian Sternagel wrote: Dear all, please find attached patches for localizing src/Tools/Adhoc_Overloading.thy. I will take care to apply the changesets to Isabelle and AFP. (Later there might be more tips coming about the implementation techniques, but I first need to study the text again.) Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Fri, 12 Jul 2013, Makarius wrote: On Fri, 12 Jul 2013, Christian Sternagel wrote: Dear all, please find attached patches for localizing src/Tools/Adhoc_Overloading.thy. I will take care to apply the changesets to Isabelle and AFP. Looking closer, I see several versions of patches. Are you still exploring, or ready for push? Which version? Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
The patches should be ready to push (for your convenience I attached them once more; the attached patches are the same as from my previous e-mail). Btw, I generated the patches against Isabelle 8afb396d9178 and AFP 908304753f7d (but I guess this information is also included in the patches ;)). cheers chris On 07/12/2013 08:38 PM, Makarius wrote: On Fri, 12 Jul 2013, Makarius wrote: On Fri, 12 Jul 2013, Christian Sternagel wrote: Dear all, please find attached patches for localizing src/Tools/Adhoc_Overloading.thy. I will take care to apply the changesets to Isabelle and AFP. Looking closer, I see several versions of patches. Are you still exploring, or ready for push? Which version? Makarius diff -r 8afb396d9178 src/HOL/Imperative_HOL/Heap_Monad.thy --- a/src/HOL/Imperative_HOL/Heap_Monad.thy Thu Jul 11 21:34:50 2013 +0200 +++ b/src/HOL/Imperative_HOL/Heap_Monad.thy Fri Jul 12 19:19:43 2013 +0900 @@ -274,10 +274,8 @@ Some (x, h') \Rightarrow execute (g x) h' | None \Rightarrow None) -setup {* - Adhoc_Overloading.add_variant -@{const_name Monad_Syntax.bind} @{const_name Heap_Monad.bind} -*} +adhoc_overloading + Monad_Syntax.bind Heap_Monad.bind lemma execute_bind [execute_simps]: execute f h = Some (x, h') \Longrightarrow execute (f \guillemotright= g) h = execute (g x) h' diff -r 8afb396d9178 src/HOL/Library/Monad_Syntax.thy --- a/src/HOL/Library/Monad_Syntax.thy Thu Jul 11 21:34:50 2013 +0200 +++ b/src/HOL/Library/Monad_Syntax.thy Fri Jul 12 19:19:43 2013 +0900 @@ -69,12 +69,7 @@ _do_block (_do_final e) = e (m n) = (m = (\lambda_. n)) -setup {* - Adhoc_Overloading.add_overloaded @{const_name bind} - # Adhoc_Overloading.add_variant @{const_name bind} @{const_name Set.bind} - # Adhoc_Overloading.add_variant @{const_name bind} @{const_name Predicate.bind} - # Adhoc_Overloading.add_variant @{const_name bind} @{const_name Option.bind} - # Adhoc_Overloading.add_variant @{const_name bind} @{const_name List.bind} -*} +adhoc_overloading + bind Set.bind Predicate.bind Option.bind List.bind end diff -r 8afb396d9178 src/Tools/Adhoc_Overloading.thy --- a/src/Tools/Adhoc_Overloading.thy Thu Jul 11 21:34:50 2013 +0200 +++ b/src/Tools/Adhoc_Overloading.thy Fri Jul 12 19:19:43 2013 +0900 @@ -6,10 +6,10 @@ theory Adhoc_Overloading imports Pure +keywords adhoc_overloading :: thy_decl and no_adhoc_overloading :: thy_decl begin ML_file adhoc_overloading.ML -setup Adhoc_Overloading.setup end diff -r 8afb396d9178 src/Tools/adhoc_overloading.ML --- a/src/Tools/adhoc_overloading.ML Thu Jul 11 21:34:50 2013 +0200 +++ b/src/Tools/adhoc_overloading.ML Fri Jul 12 19:19:43 2013 +0900 @@ -6,11 +6,14 @@ signature ADHOC_OVERLOADING = sig - val add_overloaded: string - theory - theory - val add_variant: string - string - theory - theory - + val is_overloaded: Proof.context - string - bool + val generic_add_overloaded: string - Context.generic - Context.generic + val generic_remove_overloaded: string - Context.generic - Context.generic + val generic_add_variant: string - term - Context.generic - Context.generic + (*If the list of variants is empty at the end of generic_remove_variant, then + generic_remove_overloaded is called implicitly.*) + val generic_remove_variant: string - term - Context.generic - Context.generic val show_variants: bool Config.T - val setup: theory - theory end structure Adhoc_Overloading: ADHOC_OVERLOADING = @@ -18,122 +21,208 @@ val show_variants = Attrib.setup_config_bool @{binding show_variants} (K false); - (* errors *) -fun duplicate_variant_err int_name ext_name = - error (Constant ^ quote int_name ^ is already a variant of ^ quote ext_name); +fun duplicate_variant_error oconst = + error (Duplicate variant of ^ quote oconst); -fun not_overloaded_err name = - error (Constant ^ quote name ^ is not declared as overloaded); +fun not_a_variant_error oconst = + error (Not a variant of ^ quote oconst); -fun already_overloaded_err name = - error (Constant ^ quote name ^ is already declared as overloaded); +fun not_overloaded_error oconst = + error (Constant ^ quote oconst ^ is not declared as overloaded); -fun unresolved_err ctxt (c, T) t reason = - error (Unresolved overloading of ^ quote c ^ :: ^ +fun unresolved_overloading_error ctxt (c, T) t reason = + error (Unresolved overloading of ^ quote c ^ :: ^ quote (Syntax.string_of_typ ctxt T) ^ in ^ quote (Syntax.string_of_term ctxt t) ^ ( ^ reason ^ )); +(* generic data *) -(* theory data *) +fun variants_eq ((v1, T1), (v2, T2)) = + Term.aconv_untyped (v1, v2) andalso T1 = T2; -structure Overload_Data = Theory_Data +structure Overload_Data = Generic_Data ( type T = -{ internalize : (string * typ) list Symtab.table, - externalize : string Symtab.table }; - val empty = {internalize=Symtab.empty, externalize=Symtab.empty}; +{variants : (term * typ) list
Re: [isabelle-dev] adhoc overloading
On Fri, 12 Jul 2013, Christian Sternagel wrote: The patches should be ready to push (for your convenience I attached them once more; the attached patches are the same as from my previous e-mail). Btw, I generated the patches against Isabelle 8afb396d9178 and AFP 908304753f7d (but I guess this information is also included in the patches ;)). This is now Isabelle/e0ff1625e96d and AFP/74746c992248. Since you did not provide formal changesets, only diffs, I invented some log messages on the spot. (Normally I use the hg export / hg import pair for small-scale patch-flow, but hg import was happy importing plain diffs like this.) I added Isabelle/fee0db8cf60d to keep the generated Proof General keyword tables in sync. This is now trivial with the isabelle update_keywords tool in its fully static version. (In the past there was always a full build required before applying it, or a good guess which sessions contribute to the keyword tables.) Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
Dear all, here is an update to my previous message. Corresponding patches are attached (tested with `isabelle build_doc -pa` and `isabelle afp_build -A`). Some comments: 1) Variants are stored as terms but where all types are mapped to dummyT (which makes it easier to check for a given term, whether it is a variant of an overloaded constant). 2) In the table that maps overloaded constants to variants in addition to the dummy-typed variant also a type is included (where all free type variables are replaced by schematic ones). 3) As stated by Dmitriy in the type unification thread the current solution does not work for localization (but the corresponding change is trivial, I'm just avoiding it for the moment, since without localization I have to work with a thy, which is inconvenient to turn into a ctxt as required by Variable.polymorphic). cheers chris On 07/10/2013 04:38 PM, Christian Sternagel wrote: First of all, thanks for all the useful answers and sorry for my late reply (I visited a conference and had some holidays ;)). As Alexander suggested, I first tried to modify the existing adhoc_overloading.ML in such a way that variants may be arbitrary terms. Please find the results of my attempt attached (the new adhoc_overloading.ML as well as a patch-file). Now I will investigate further localization. Any comments are welcome. cheers chris On 06/02/2013 08:55 AM, Alexander Krauss wrote: Hi Chris, I'm currently (as of changeset e6433b34364b) investigating whether it would be possible to allow adhoc overloading (implemented in ~~/src/Tools/adhoc_overloading.ML) inside local contexts. Nice! For completeness find my current adhoc_overloading.ML attached Apart from the various formalities pointed out by Makarius, here is another concern, which relates to Florian's earlier question about how local you want to be... Currently, Adhoc_Overloading replaces constants with other constants, which makes it global-only. Your current version tries to deal with Frees similarly, it's not just that. Recall the example you gave previously: consts FOO :: ... (some syntax) setup {* Adhoc_Overloading.add_overloaded @{const_name FOO} *} locale foo = fixes foo :: ... assumes ... begin local_setup {* Adhoc_Overloading.add_variant @{const_name FOO} @{term foo} *} Now consider the following interpretation: interpretation foo some term proof Now, some term should become a variant of FOO, so at least the variant side of the overloading relation must be an arbitrary term. With your current code, the overloading would only survive interpretations where foo happens to be mapped to a constant. So, I guess that the overloaded constants should remain constants, since they are just syntactic anyway. It seems that localizing those would be rather artificial. But the variants must be properly localized and subject to the morphism. As a step towards proper localization, you could start with the global code, and first generalize it to accept arbitrary terms as variants. Note that this touches in particular the uncheck phase, which can no longer use Term_Subst.map_aterms_same (or Term.map_aterms), since it becomes general rewriting. One must resort to the more general Pattern.rewrite_term here. When all this is working again, the actual localization is then a mere formality, of which you have already discovered the ingredients. Makarius wrote: * Same.function seems to be a let-over from the version by Alex Krauss. He had that once in his function package, copied from somewhere else (probably old code of mine). No, it has nothing to do with the function package, which never used any Same stuff. It just arose rather naturally from the requirement to return NONE when nothing changes... So it was not meant as an optimization. There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only So should I manually check the result for equality, or does the framework do this for me? Alex diff -r aaec3f5a1ba6 thys/JinjaThreads/Framework/FWState.thy --- a/thys/JinjaThreads/Framework/FWState.thy Wed Jul 10 15:19:23 2013 +0200 +++ b/thys/JinjaThreads/Framework/FWState.thy Thu Jul 11 16:30:08 2013 +0900 @@ -190,12 +190,12 @@ setup {* Adhoc_Overloading.add_overloaded @{const_name inject_thread_action} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name NewThreadAction} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name ConditionalAction} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name WaitSetAction} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name InterruptAction} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name ObsAction} - # Adhoc_Overloading.add_variant @{const_name inject_thread_action} @{const_name LockAction} + #
Re: [isabelle-dev] adhoc overloading
First of all, thanks for all the useful answers and sorry for my late reply (I visited a conference and had some holidays ;)). As Alexander suggested, I first tried to modify the existing adhoc_overloading.ML in such a way that variants may be arbitrary terms. Please find the results of my attempt attached (the new adhoc_overloading.ML as well as a patch-file). Now I will investigate further localization. Any comments are welcome. cheers chris On 06/02/2013 08:55 AM, Alexander Krauss wrote: Hi Chris, I'm currently (as of changeset e6433b34364b) investigating whether it would be possible to allow adhoc overloading (implemented in ~~/src/Tools/adhoc_overloading.ML) inside local contexts. Nice! For completeness find my current adhoc_overloading.ML attached Apart from the various formalities pointed out by Makarius, here is another concern, which relates to Florian's earlier question about how local you want to be... Currently, Adhoc_Overloading replaces constants with other constants, which makes it global-only. Your current version tries to deal with Frees similarly, it's not just that. Recall the example you gave previously: consts FOO :: ... (some syntax) setup {* Adhoc_Overloading.add_overloaded @{const_name FOO} *} locale foo = fixes foo :: ... assumes ... begin local_setup {* Adhoc_Overloading.add_variant @{const_name FOO} @{term foo} *} Now consider the following interpretation: interpretation foo some term proof Now, some term should become a variant of FOO, so at least the variant side of the overloading relation must be an arbitrary term. With your current code, the overloading would only survive interpretations where foo happens to be mapped to a constant. So, I guess that the overloaded constants should remain constants, since they are just syntactic anyway. It seems that localizing those would be rather artificial. But the variants must be properly localized and subject to the morphism. As a step towards proper localization, you could start with the global code, and first generalize it to accept arbitrary terms as variants. Note that this touches in particular the uncheck phase, which can no longer use Term_Subst.map_aterms_same (or Term.map_aterms), since it becomes general rewriting. One must resort to the more general Pattern.rewrite_term here. When all this is working again, the actual localization is then a mere formality, of which you have already discovered the ingredients. Makarius wrote: * Same.function seems to be a let-over from the version by Alex Krauss. He had that once in his function package, copied from somewhere else (probably old code of mine). No, it has nothing to do with the function package, which never used any Same stuff. It just arose rather naturally from the requirement to return NONE when nothing changes... So it was not meant as an optimization. There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only So should I manually check the result for equality, or does the framework do this for me? Alex (* Author: Alexander Krauss, TU Muenchen Author: Christian Sternagel, University of Innsbruck Ad-hoc overloading of constants based on their types. *) signature ADHOC_OVERLOADING = sig val add_overloaded: string - theory - theory val add_variant: string - term - theory - theory val show_variants: bool Config.T val setup: theory - theory end structure Adhoc_Overloading: ADHOC_OVERLOADING = struct val show_variants = Attrib.setup_config_bool @{binding show_variants} (K false); (* errors *) fun duplicate_variant_error ext_name = error (Duplicate variant of ^ quote ext_name); fun not_overloaded_error name = error (Constant ^ quote name ^ is not declared as overloaded); fun already_overloaded_error name = error (Constant ^ quote name ^ is already declared as overloaded); fun unresolved_overloading_error ctxt (c, T) t reason = error (Unresolved overloading of ^ quote c ^ :: ^ quote (Syntax.string_of_typ ctxt T) ^ in ^ quote (Syntax.string_of_term ctxt t) ^ ( ^ reason ^ )); (* theory data *) structure Overload_Data = Theory_Data ( type T = {internalize : term list Symtab.table, externalize : string Termtab.table}; val empty = {internalize = Symtab.empty, externalize = Termtab.empty}; val extend = I; fun merge_ext _ (ext_name1, ext_name2) = if ext_name1 = ext_name2 then ext_name1 else duplicate_variant_error ext_name1; fun merge ({internalize = int1, externalize = ext1}, {internalize = int2, externalize = ext2}) : T = {internalize = Symtab.merge_list (op aconv) (int1, int2), externalize = Termtab.join merge_ext (ext1, ext2)}; ); fun map_tables f g = Overload_Data.map (fn {internalize = int, externalize = ext} = {internalize = f int, externalize = g ext}); val is_overloaded = Symtab.defined o #internalize o Overload_Data.get; val
Re: [isabelle-dev] adhoc overloading
There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only So should I manually check the result for equality, or does the framework do this for me? See http://isabelle.in.tum.de/repos/isabelle/file/41d7946e2595/src/Pure/Syntax/syntax_phases.ML#l854 There are two variants of interfaces adding functions to check phases: one with explicit hinting by the check function via None/Some, the other one with check by the framework. Florian -- PGP available: http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_informatik_tu_muenchen_de signature.asc Description: OpenPGP digital signature ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
Hi Chris, I'm currently (as of changeset e6433b34364b) investigating whether it would be possible to allow adhoc overloading (implemented in ~~/src/Tools/adhoc_overloading.ML) inside local contexts. Nice! For completeness find my current adhoc_overloading.ML attached Apart from the various formalities pointed out by Makarius, here is another concern, which relates to Florian's earlier question about how local you want to be... Currently, Adhoc_Overloading replaces constants with other constants, which makes it global-only. Your current version tries to deal with Frees similarly, it's not just that. Recall the example you gave previously: consts FOO :: ... (some syntax) setup {* Adhoc_Overloading.add_overloaded @{const_name FOO} *} locale foo = fixes foo :: ... assumes ... begin local_setup {* Adhoc_Overloading.add_variant @{const_name FOO} @{term foo} *} Now consider the following interpretation: interpretation foo some term proof Now, some term should become a variant of FOO, so at least the variant side of the overloading relation must be an arbitrary term. With your current code, the overloading would only survive interpretations where foo happens to be mapped to a constant. So, I guess that the overloaded constants should remain constants, since they are just syntactic anyway. It seems that localizing those would be rather artificial. But the variants must be properly localized and subject to the morphism. As a step towards proper localization, you could start with the global code, and first generalize it to accept arbitrary terms as variants. Note that this touches in particular the uncheck phase, which can no longer use Term_Subst.map_aterms_same (or Term.map_aterms), since it becomes general rewriting. One must resort to the more general Pattern.rewrite_term here. When all this is working again, the actual localization is then a mere formality, of which you have already discovered the ingredients. Makarius wrote: * Same.function seems to be a let-over from the version by Alex Krauss. He had that once in his function package, copied from somewhere else (probably old code of mine). No, it has nothing to do with the function package, which never used any Same stuff. It just arose rather naturally from the requirement to return NONE when nothing changes... So it was not meant as an optimization. There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only So should I manually check the result for equality, or does the framework do this for me? Alex ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Fri, 31 May 2013, Christian Sternagel wrote: - To set up a command (adhoc_overloading in my case) that should also work inside local contexts I use Outer_Syntax.local_theory. This is fine. Basically you make some concrete syntax for this: syntax_declaration {* fn phi = fn context = update (transform phi data) context *} See also http://www4.in.tum.de/~wenzelm/papers/context-methods.pdf section 3, especially 3.4. - For data related to the command I use Generic_Data (since it should be available in top-level theories as well as local contexts). Yes, and for any update operation you need to work uniformly with Context.generic, not attempt any special things (like updating the background theory of a Proof.context!). - Investigating notation a bit (but not understanding the implementation details ;)), I suspect that Local_Theory.declaration is used to make changes in my Generic_Data persistent. What is the purpose of the {syntax: bool, pervasive: bool} argument of Local_Theory.declaration. 'declaration' is the general abstract non-sense of the local everything approach; section 3.4 also explains that 'declare' happens to be equivalent due to the flexibility of attributes -- at least at the level of abstraction of the paper. The additional flags syntax and pervasive are only available to the full Local_Theory.declaration and actual Isar commands built on top of that, not in the declare attribute form. syntax gives it a special status in the bootstrap process of locale expressions. So you better enable that flag here, like 'notation' does. pervasive means it would write through all layers of the Haftmann-Wenzel Sandwich (which is now a Neapolitan wafer -- as an Austrian you should know what it is). This is better disabled for syntax things. - Local_Theory.declaration expects a declaration as argument, which abbreviates the type morphism - Context.generic - Context.generic. For the time being I just ignore morphism (of course I will have to understand and incorporate it at some point). Ignoring the morphism means it only works in the global theory context, where it is the identify. The local everything approach is about getting the handling the morphism right wrt. your update function on the tool-specific data, when it is applied to a particular target context. - So far so good. Everything compiles fine. When I actually use my newly defined command, I get the error Stale theory encountered. So obviously I'm doing something wrong in the above f (if I replace f by I the error disappears, but of course then I can also not make changes in my Generic_Data persistent.) I can't say on the spot what is wrong, apart from some oddities. Why have Context.mapping with Context.theory_map/proof_map in the first place? You should be able to work on Context.generic directly to update your generic data. Moreover, you need to get naming conventions right: lthy : local_theory refers to the full Haftmann-Wenzel Sandwich, but as you apply updates to particular target contexts it is no longer that. So it should be just ctxt = Context.proof_of context for read_const. More hints when I've studied the rest of the examples setup ... Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Fri, 31 May 2013, Christian Sternagel wrote: - So far so good. Everything compiles fine. When I actually use my newly defined command, I get the error Stale theory encountered. So obviously I'm doing something wrong in the above f (if I replace f by I the error disappears, but of course then I can also not make changes in my Generic_Data persistent.) The f is the theory - theory case, so the good old linearity-of-update principle applies. Your overload_cmd / gen_overload looks non-linear wrt. the initial context: you need to refer to the updated one in every step of the fold, not the initial one as a constant that has been updated already. Generally, you don't have to make everything work on Context.generic. Read-only functions like unresolved_overloading_error are fine with a plain ctxt : Proof.context, and logical operations like unifiable_with using old-style thy : theory. As a rule of thumb, you have Proof.context most of the time, theory rarely, Context.generic and its funny embedding and conversion operations only when maintaining generic data in some declaration (or attribute). adhoc_overloading foo foo_list parses foo and foo_list with Parse.const and preprocesses all its arguments by Proof_Context.read_const ctxt false dummyT, which I thought was the canonical way to check whether a string is a (locally fixed) constant. As a general principle, you internalize user input only once in the outermost command (potentially with user error). Then you turn it into some canonical logical entity (type, term, fact), and apply that in the declaration after tranforming it via the morphism you get eventually. So lets say your constant name first looks like a Const or Free. Then in the second stage, that internal form is transformed by some term morphism. You check if it still looks fine (Const or Free) and do the right thing; if not you give up your data without failing (sometimes warnings help, sometimes warnings are just noisy). For completeness find my current adhoc_overloading.ML attached (but be aware that it is far from finished; it is merely a sandbox in which I play to find out more about the internals of Isabelle). A few more hints on that file: * If you inline that small adhoc_overloding.ML into the theory as ML section, it will be just one piece in the end for users to import. * Same.function seems to be a let-over from the version by Alex Krauss. He had that once in his function package, copied from somewhere else (probably old code of mine). There is no point to do such low-level optimizations in the syntax layer. It is for hardcore kernel operations only, to make them hard to understand and look terrific. * variant_tab as a name is a bit bulky; consider using just variants. * Symtab.delete is strict, it will fail if the element is absent. Consider using permissive Symtab.delete_safe by default, or other variants like Symtab.remove. Sorry for the lengthy email, but it's really hard to find your way through the existing Isabelle/ML API without professional help ;) Reading the sources alone won't help here -- you need to develop a feeling for the kind of music that is played when looking at the score, err source. Maybe you know the end of the film Amadeus http://en.wikipedia.org/wiki/Amadeus_%28film%29 where you have Mozart lying sick in bed and dictating some great music to Salieri. That guy then just produces a few black marks on the paper, but the real thing happens in the mind of the composer (for illustration it is also made audible for the one who watches the movie). Confutatis maledictis flammis acribus addictis, etc. In the very end of the film Salieri gets insane, but that is another story ... Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Wed, 29 May 2013, Florian Haftmann wrote: Alternatively, use Context. directly in the body of the ML file (which, I guess, is nowadays preferred over explicit setup in the surrounding theory). Hypersearch over the sources shows that Context. is still quite rare, and there is no trend to be seen yet. Of course, a trend could be started now. Last time we've discussed that privately, you were more in favour of setup and I more in favour of Context. (quite some years ago). I am myself used to Context. in Isabelle/Pure (there is no other way), and I follow the old habit with 'setup' in Isabelle/HOL most of the time. On the other hand, the received two-part idiom is a bit odd wrt. proper modularity: ML_file foo.ML setup Foo.setup Like two-component glue to be fit together by hand. It used to be three components until recently, with extra uses in the theory header. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
Dear all, as I said earlier I am trying to make some changes (in Generic_Data) persistent from inside a command. (My special case is ad-hoc overloading, but I think that is irrelevant for the following.) My current setup is (could you please point out any inadequate choices): - To set up a command (adhoc_overloading in my case) that should also work inside local contexts I use Outer_Syntax.local_theory. - For data related to the command I use Generic_Data (since it should be available in top-level theories as well as local contexts). - Investigating notation a bit (but not understanding the implementation details ;)), I suspect that Local_Theory.declaration is used to make changes in my Generic_Data persistent. What is the purpose of the {syntax: bool, pervasive: bool} argument of Local_Theory.declaration. - Local_Theory.declaration expects a declaration as argument, which abbreviates the type morphism - Context.generic - Context.generic. For the time being I just ignore morphism (of course I will have to understand and incorporate it at some point). So my declaration is essentially a call to Context.mapping which takes two mappings: f for theory - theory and g for Proof.context - Proof.context. - So far so good. Everything compiles fine. When I actually use my newly defined command, I get the error Stale theory encountered. So obviously I'm doing something wrong in the above f (if I replace f by I the error disappears, but of course then I can also not make changes in my Generic_Data persistent.) - Even if f is replaced by I above, something I do not understand happens w.r.t. g. But this is specific to my adhoc_overloading so I have to give some more details: adhoc_overloading foo foo_list parses foo and foo_list with Parse.const and preprocesses all its arguments by Proof_Context.read_const ctxt false dummyT, which I thought was the canonical way to check whether a string is a (locally fixed) constant. Now inside a local context context fixes foo_nat :: nat begin I try adhoc_overloading foo foo_nat And obtain Unknown constant: foo_nat When adding some debug output to my internal function I obtain the following before the error: checking constant: foo const DONE. checking constant: foo_nat free DONE. checking constant: foo const DONE. checking constant: foo_nat Unknown constant: foo_nat Which tells me that once foo_nat is parsed as a locally fixed constant (represented by a Free variable) as expected. What I did not expect was that all the arguments are considered a second time (so actually g is called twice). In this second run we are apparently in a different context, since foo_nat is no longer locally fixed. I'm sure that this is the correct behavior, but maybe someone could explain it to me. For completeness find my current adhoc_overloading.ML attached (but be aware that it is far from finished; it is merely a sandbox in which I play to find out more about the internals of Isabelle). Sorry for the lengthy email, but it's really hard to find your way through the existing Isabelle/ML API without professional help ;) cheers chris On 05/31/2013 06:08 AM, Makarius wrote: On Wed, 29 May 2013, Florian Haftmann wrote: Alternatively, use Context. directly in the body of the ML file (which, I guess, is nowadays preferred over explicit setup in the surrounding theory). Hypersearch over the sources shows that Context. is still quite rare, and there is no trend to be seen yet. Of course, a trend could be started now. Last time we've discussed that privately, you were more in favour of setup and I more in favour of Context. (quite some years ago). I am myself used to Context. in Isabelle/Pure (there is no other way), and I follow the old habit with 'setup' in Isabelle/HOL most of the time. On the other hand, the received two-part idiom is a bit odd wrt. proper modularity: ML_file foo.ML setup Foo.setup Like two-component glue to be fit together by hand. It used to be three components until recently, with extra uses in the theory header. Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev (* Author: Alexander Krauss, TU Muenchen Author: Christian Sternagel, University of Innsbruck Ad-hoc overloading of constants based on their types. *) signature ADHOC_OVERLOADING = sig val is_overloaded: Context.generic - string - bool val overload: bool - string - Context.generic - Context.generic val variant: bool - string - (string * typ) - Context.generic - Context.generic val show_overloaded: bool Config.T end structure Adhoc_Overloading: ADHOC_OVERLOADING = struct val show_overloaded = Attrib.setup_config_bool @{binding show_overloaded} (K true); (* errors *) fun already_overloaded_error oconst = error (Constant ^ quote oconst ^ is already
Re: [isabelle-dev] adhoc overloading
Hi Christian, - For Overload_Data instead of Theory_Data, I should use Generic_Data (such that it is available in top-level theories and local theories). Currently that means that I do the following in the setup (where Adhoc_Overloading.setup is now of type Context.generic - Context.generic). setup {* fn thy = Adhoc_Overloading.setup (Context.Theory thy) Context.theory_of *} This looks strange, I'm sure I'm doing something wrong / non-canonical. I think Adhoc_Overloading.setup should stay theory - theory: this is the installation of the necessary syntax check phases, which is done once globally on import of the corresponding theory – unlike the dynamic addition via add_overloaded and add_variant Alternatively, use Context. directly in the body of the ML file (which, I guess, is nowadays preferred over explicit setup in the surrounding theory). - Apparently constants (in the sense of locally fixed variables of a local theory) are represented as terms rather than strings (in the notation command). In adhoc_overloading.ML, until now we used strings to represent top-level constants. A change (if really necessary) implies the following questions: It depends how far you want to push the game. * The simplest one I can imagine is to stay on the »constant as string« level, but have declarations within local theories; if these would be morphed e.g. due to interpretation, they would only be kept if their resulting shape is again a constant. * Treat one component as general term appropriately (maybe the variant?). * Treat both components as general term appropriately. * How to print a constant represented as term in the error messages inside Overload_Data (I do not see how I could access the context here) Good question. Note that most »fully localized« data store prefer Item_Net.T as store index, where merge always seems to prefer on branch (I only did skim over the sources, so this conclusion might be erroneous). * I also would like to add the possibility to remove overloading and variants again. Is that against some monotonicity requirement I'm not aware of? It should work, with the usual problems on the theory level that things deleted in one theory come up again after merge with another theory with partly shared but different ancestry. - Concerning syntax, I thought about providing commands like: adhoc_overloading bind bind_list bind_option and permute permute_list permute_option (which would declare bind and permute as ad-hoc overloaded and add the variants bind_list and bind_option, and permute_list and permute_option, respectively.) Maybe some punctuation between the overloaded constant and its variant would increase readability? Maybe \rightharpoonup / = similar to existing syntax things= - In the check and uncheck functions I now would have to unify typed terms instead of mere constants. Could that be too expensive to be practicable? I have no particular idea about that. Cheers, Florian -- PGP available: http://home.informatik.tu-muenchen.de/haftmann/pgp/florian_haftmann_at_informatik_tu_muenchen_de signature.asc Description: OpenPGP digital signature ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev
Re: [isabelle-dev] adhoc overloading
On Fri, 24 May 2013, Christian Sternagel wrote: Since I'm not too sure about the internals of local contexts, would that make sense in principle? Yes. According to the local everything approach from 2006, locality is the normal situation unless there are very strong reasons against it. In practice, non-locality is merely historic in most cases, and the effort to get things to the normal local state is called localization. For the declarations of Adhoc_Overloading (add_overloaded, add_variant) you merely need to address the usual questions what it means to transform them via a morphism, and then apply the result to concrete contexts in the applications. A usual starting point is to look how existing similar mechanism do that, lets say notation that is associated with constant terms. A related question: what is the difference between Syntax_Phases.term_check and Syntax_Phases.term_check'? Why does the latter expect a function returning an option but not the former? Syntax_Phases.term_check' allows full generality, with a functions that indicates a stable situation by NONE, to represent identity explicitly. The more common Syntax_Phases.term_check merely applies the given total function and compares the visible part of the result (the types/terms) to see if stability was achieved. You need the ' version in particular, when the context changes and not just the types/term material, e.g. setting some flags that you have seen a certain situation already. And another one: assume we could do consts FOO :: ... (some syntax) setup {* Adhoc_Overloading.add_overloaded @{const_name FOO} *} locale foo = fixes foo :: ... assumes ... begin local_setup {* Adhoc_Overloading.add_variant @{const_name FOO} @{const_name foo} *} would the overloading only be active inside foo or would it also have effects outside of this context (that are impossible to avoid due to technical reasons)? Does it make sense at all to use the locally fixed foo as a constant in the call to add_overloaded? The local_setup above is technically a 'declaration' within the local theory context (or other application contexts). The morphism that transforms your original data from the immediate auxiliary context of the local definition to the application context gives you some clues about what to do, and when to give up the update of the context at hand. (The latter needs to be done gracefully, without an error.) As a start, I recommend to imitate 'notation' to some extent. (That is itself not beyond reform, but that is another story.) Makarius ___ isabelle-dev mailing list isabelle-...@in.tum.de https://mailmanbroy.informatik.tu-muenchen.de/mailman/listinfo/isabelle-dev