Given word/1
,
word(W) :-
abs(ABs),
ABs = W.
abs([]).
abs([AB|ABs]) :-
abs(ABs),
ab(AB).
ab(a).
ab(b).
?- word(W).
W = []
; W = [a]
; W = [b]
; W = [a,a]
; W = [b,a]
; W = [a,b]
; W = [b,b]
; W = [a,a,a]
; W = [b,a,a]
; W = [a,b,a]
; W = [b,b,a]
; W = [a,a,b]
; W = [b,a,b]
; W = [a,b,b]
; W = [b,b,b]
; W = [a,a,a,a]
...
how does a more compact definition of word/1
look like, otherwise identical w.r.t. termination and the set of solutions, fairness, with the following constraints:
No use of built-ins like
(=)/2
.No use of control constructs like
(',')/2
or(;)/2
, orcall/1
.Uses one fact, one recursive rule, and one rule for
word/1
.
Maybe simpler is to ask for the terms F1
... F4
in:
word(W) :-
p(F1).
p(F2).
p(F3) :-
p(F4).
For the record: The property exploited here is closely related to the undecidability of termination of a single binary clause. Praise goes to:
Philippe Devienne, Patrick Lebègue, Jean-Christophe Routier, and Jörg Würtz. One binary horn clause is enough STACS '94.
The solution I have come up with is:
Sample query and answer:
I am using a difference list to incrementally materialize the solutions I want the toplevel to report.
So to clarify, the intended solution is an instance of the following schema?
Where each occurrence of an
Args
variable stands for zero or more terms and presumably (but not necessarily)fact
andrecursive_rule
are actually the same functor?Okay so not an answer yet.
The closest I had was :
Which does not either meet the criteria or give the right solutions!
So next I thought we could try and use prolog to find the answer.. The structure is given so we need to search for the args..
We would still need to define :
a
andb
somewhere and probably[]
.Clearly not finished and not sure if it will be possible to do this but thought I would post an answer to see what people have to say.. The search is naive at the moment!
This is only testing the first 16 solutions but maybe that is adequate to get a correct answer..
Also maybe this is harder then solving the question on its own!
With Guy coder's suggestions this is closer?
Normally I would post these as a single answer, but @false asked me to keep them separate.
If you read my comments and answers you will see that I was aware that I had to pass the result from one iteration back into the next iteration. What gave me insight into that was using a cross-product predicate which I found in
"The Craft of Prolog" by Richard A. O'Keefe pg. 243
If you are serious about learning Prolog, the book is a must have.
To quote the Preface
Here is a slight variation that I used for one variation that did not work.
My closest yet.
If you look you will see that there is no use of
;
which I am sure is a problem some people are having. Also all of the rules are simple enough that they should be able to be folded into the requirements by using additional arguments. e.g.unfold(A,B)
would becomeunfold(A,B,C,D)
or a variation.The problem with this version is that I get the correct answers as the evaluation progresses, it is just getting them back to the top level.
e.g.
I will keep working on this before the dead line, but if someone is able to use what I have here, hats off to them, I just ask that you give credit if any part of this helped you get the answer.
The
unfold
predicate is based on this SO answer. Credit to salvamember
is an old friend. Notice that it starts with[[]]
and not[]
.swap
I created this predicate. I have swap working for different variation yet the variation fails for a different reason.Supplement
Debugger output of mat's answer
I looked at Mat's answer more closely with a debugger because it might hold the answer to a similar problem where I can generate the answers but not return them independently to Top.
Mat's answer copied here for reference.
The part of interest is far to the right as comments. I would suggest that you copy from here and past into a app that allows you to see all of the line without wrapping or hidden.
The column on the left was created with SWI-Prolog running the query with
trace
and the comments on the right were created by running the query withgtrace
and hand copying the values and noting the level for indentation.