I don't get where the `-` comes from in `key-value` result lines after the "refactoring" title. I feel like it should stay a `,` like at the beginning. Can someone more knowledgeable in Prolog explain that? Is that because of an hidden use of this `to_list` predicate that comes later in the post?
(The initial version of this comment missed the point of your question; sorry.) The author says:
> We also store pairs as the pair type (Key-Value), instead of two separate values. This makes easy to serialize a dictionary into a list of pairs, which are sortable using the builtin keysort/2.
`Key, Value` is two values, not one. I suspect something like `kv(Key, Value)` would work as well.
By the way, I disagree that the refactored version doesn't cut; `-> ;` is syntactic sugar over a cut.
It's purely a convention to use terms of the form "key - value" for 2-tuples here (or '-'(key, value) in funtional/canonical notation which can be used as well). minus is just used because it's already predeclared as an infix operator, and indeed ','(key, value) could be used as well but comma is also used as argument separator and for conjunctions in clause bodies and thus tends to be avoided. You also can see '=' being used for the same thing eg.
[ key = value, ...]
(for example, as used for representing attributes by SGML/XML parsing libs for SWI, Quintus/SICStus, and others), not to be confused with '=' being interpreted as unification operation in goals/clause bodies.If you think about it, the simplest convention in Prolog to represent "assignment" of a value to a symbol (not a variable) would be
key(value).
That is, to use the "key" atom as functor itself, rather than use functors/operators in ad-hoc ways. This is exactly what Quantum Prolog can do (optionally, and in addition to ISO Prolog's conventions).Specifically, if you have a list of fact-like terms
L = [ p(1), q(2), r(what(ever)) ]
then Quantum Prolog can answer queries against such term list, just like answering against the global default database eg. call(L ?- q(X))
binds X = 2
and would also bind additional values for q(X) on backtracking if the term list contained any. This is a natural extension to regular querying in Prolog because a term list [a, b] in Prolog's square bracket notation is just syntactic sugar for using the dot operator '.'(a, '.'(b, []))
and a Prolog program is syntactically just a list of clause terms.In the container planning demo on the Quantum Prolog site [1], this feature is used for backtracking over (un)loading and travelling actions which would normally change state via destructive assert and retract calls and hence not allow backtracking to search for optimal sequences of actions.
[1]: https://quantumprolog.sgml.net/container-planning-demo/part2...
Operators like - are just an infix functor for a Prolog term with arity 2:
Functors like - only become arithmetic in combination with is: