Strings as lists of CLP(Z) characters! #904
Replies: 4 comments 18 replies
-
I'll try the example and see if I can't find the time sink. |
Beta Was this translation helpful? Give feedback.
-
Independently of the modeling question, I think a worthwhile question to ask is: Are these the kind of answers we want to see on the toplevel, and when reasoning about the program (during slicing, tracing, debugging etc.)? The key attraction of using characters instead of codes is that characters are so nicely readable, and for this reason Scryer Prolog has dedicated support for them in the form of a very compact and efficient representation. So, I think working with characters is overall much preferable. If too much manual work becomes involved when writing a parser over characters, I think this should be taken as a sign and motivation to search for better abstractions. For example, a predicate like Another approach could be to automatically generate a lower-level parser with all necessary tests from a more declarative description when the library is loaded. I'm using this approach to generate many predicates of |
Beta Was this translation helpful? Give feedback.
-
Example. You can delay the goal with
For writing, the character must be instantiated. (Will the user generate all the possible JSON or only one specifically?)
Not possible currently, for that you need to attach to a variable information (its type), attributed variables can achieve that. But you will have a lot to develop like Or you can instantiate a solution but for each choice point at worse you have 1112063 choices (even with 2) the power doesn't look good. Other solutions?
You still have to generate the domain manually (always updating to keep up with unicode) or automatically (term expansion but slow). If you generate it then why not a domain of atom (add a system predicate for next atom)? You could extend
The library Line: |
Beta Was this translation helpful? Give feedback.
-
This is a very nice attempt. There is a lot to say about it. Well, I will just string out one of the most relevant points first. 1mo, it seems that you are a bit annoyed by the instantiation errors Prolog produced. Don't! Sadly, these errors got a very bad rap, although they are one of the key elements of making otherwise impure, inefficient or ineffective code pure and that with reasonable effort. Rest assured, you are not the first to be annoyed. In fact, in the transition from Prolog I (dit Marseille Prolog) to Edinburgh Prolog (DEC10 Prolog) all meticulously designed errors were replaced by silent failure or even worse means. And to the present day we are still recovering from this decision. Also in your code there are such impure parts that would profit from instantiation errors. Think of 2do, you are encoding Unicode's highly irregular structure with the domain description of CLP(Z). But note that you are not really using the CLP(Z) functionality at all. It's rather this 3tio, on the advantages of 4to, for the annoyance, there is more to come. Think of non-termination which nevertheless is preferable to incorrect answers. But don't despair, it's Programmation en logique and not sans logique. (And, if you are still here and interested in using CLP(Z) in a pure manner, don't forget |
Beta Was this translation helpful? Give feedback.
-
EDIT: From the discussion below, I realized that I was using CLP(Z) as a crutch because I did not know how to deal with termination and instantiation issues. Now that I understand the difference between logic and control, and that instantiation checks should be done in such a way as to not impact the logic, I'm perfectly comfortable with instantiation errors, and recognize their value. For more details, see the responses below. The approach in this original post is not a good practice.
I'm having a fantastic experience writing DCGs that reason about characters as CLP(Z) integers rather than atoms.
I began working on
library(json)
based on this official spec and was immediately bogged down with checking whether variables are instantiated, running into strange instantiation-related errors, coding around parsing/generating directions, etc. It was not fun. Here's a link to my first stab at writinglibrary(json)
.At this point I was getting very frustrated and disappointed. I felt that the promise of Prolog was broken and if I couldn't reason about things declaratively in Prolog, I might as well just stick to Python. I thought "If only I had a
char_type/2
that worked declaratively without instantiation issues." That's when it hit me that there's a limited number of characters, so it should be possible to reason about them using CLP(Z) domains.So I sat down and wrote a first version of
library(pure)
. This library provides a predicatecode_type/2
that links a code to its character type in the exact same way thatchar_type/2
does, except it does it with CLP(Z) domains. Withcode_type/2
you don't have to worry about instantiating either the character or the type.It further occurred to me that since I was now working with CLP(Z) domains, I could do more sophisticated things with boolean logic, specifically checking whether a character is in one of multiple domains or checking whether a character is NOT in a domain. So I wrote
code_incl_excl/3
which you can use to declaratively reason about characters based on the types they're of or not of, and lists they're in or not in. You can additionally usecode_incl_excl/4
to reify that reasoning to use withlibrary(reif)
.Using the above tools, I began writing a much more elegant and flexibie
library(json)
. I've only written the string parsing/generating section so far, but I'm very happy with how simple it is to write and read, and its termination properties.Example run:
The only thing that puts a dampener on my bright spirits right now is that the performance is truly awful. Even parsing the above 26 character long JSON string takes 20 seconds. I hope that this can be improved somehow...
At this point I want to solicit feedback from the community before proceeding further. Has what I've done been tried or considered before? Do you see any future in this approach? Does anyone have ideas about how to resolve the performance issue?
I greatly appreciate any and all feedback.
Beta Was this translation helpful? Give feedback.
All reactions