With a grammar like this:
as --> [].
as --> [a], as.
b(b(a)) --> as.
c(X) --> b(X).
phrase(b(X), [a, a])
& phrase(c(X), [a, a])
work no problem. Both return X = b(a).
.
But is it possible to unify something like this?
phrase(c(X), [b(a)]).
OR:
phrase(c(X), [b(b(a))]).
I've had no luck, though it seems like it should be possible. I think this means I have some misunderstanding about DCGs. I know they work through difference lists, and succeed when they can apply a series of rules to consume all the elements of the list. Is there something special about atoms or tokens as far as phrase/2
is concerned?
Here's what the trace looks like:
[trace] [4] ?- phrase(c(X), [b(a)]).
Call: (5,411) c(_57162, [b(a)], []) ? creep
Call: (5,412) b(_57162, [b(a)], []) ? creep
Call: (5,413) [b(a)]as[] ? creep
Fail: (5,413) [b(a)]as[] ? creep
Fail: (5,412) b(_57162, [b(a)], []) ? creep
Fail: (5,411) c(_57162, [b(a)], []) ? creep
false.
The failure at [b(a)]as[]
is interesting to me. What is being tested there? And... what does that syntax mean?
I know some people find it easier to answer a question when they understand a little more about what I'm actually trying to accomplish, so:
Occasionally in my application I'd like to rephrase inelegant sentences. For instance, sometimes I'll come across something like ["bake", "that" "many", "pie", "plus", "one"]
. I'd like the DCG to treat this as though it'd encountered ["bake", "x", "pie"]
instead. So I could use phrase(foo(X), ["x", "pie"])
, and if that succeeds, then I might like to wrap it in another rule higher up in the grammar. (Why not just call the higher rule to start? Some of the higher rules are very slow in my grammar, so I'm trying to "fail quickly" by testing a lower-level grammar rule first.)
Thanks in advance for any advice!