0

I've got this prolog problem I can't get around. What I'm trying to achieve is to assert FACT A, retract Fact B when I have input: take and assert Fact B and retract Fact A when I have input put.

ie:

:- dynamic s/2.
:- dynamic s/3.

s(P0, s(V, NP)) --> v(P1, V), np(P2, NP), {P0 is P1*P2*0.35}.

s(P0, s(V, NP, PP)) --> v(P1, V), np(P2, NP), pp(P3, PP), {P0 is P1*P2*P3*0.65}.
s(P0, s(V, NP)) --> v(P1, V), np(P2, NP), {V == take -> P0 is P1*P2*0.35; P0 is 0}.
s(P0, s(V, NP, PP)) --> v(P1, V), np(P2, NP), pp(P3, PP), {V == put -> P0 is P1*P2*P3*0.65; P0 is 0}.

np(P0, np(D, N)) --> det(P1, D), n(P2, N), {P0 is P1*P2*0.36}.
np(P0, np(D, A, N)) --> det(P1, D), a(P2, A), n(P3, N), {P0 is P1*P2*P3*0.46}.
np(P0, np(D, N, PP)) --> det(P1, D), n(P2, N), pp(P3, PP), {P0 is P1*P2*P3*0.13}.
np(P0, np(D, A, N, PP)) --> det(P1, D), a(P2, A), n(P3, N), pp(P4, PP), {P0 is P1*P2*P3*P4*0.05}.

pp(P0, pp(P, NP)) --> p(P1, P), np(P2, NP), {P0 is P1*P2*1.0}.

v(0.65, v(put)) --> {retract(s(V, NP))}, [put].
v(0.35, v(take)) --> {retract(s(V, NP, PP))}, [take].

n(0.23, n(block)) --> [block].
n(0.25, n(circle)) --> [circle].
n(0.15, n(cone)) --> [cone].
n(0.12, n(cube)) --> [cube].
n(0.25, n(square)) --> [square].

a(0.56, a(blue)) --> [blue].
a(0.27, a(green)) --> [green].
a(0.17, a(red)) --> [red].

det(1.0, det(the)) --> [the].

p(1.0, p(on)) --> [on].

I can't get it to work: any help would be appreciated.

EDIT: ALL OF THE CODE POSTED

false
  • 10,264
  • 13
  • 101
  • 209
macguy
  • 294
  • 3
  • 12

3 Answers3

1

I suspect the problem lies elsewhere in your code. This worked for me with SWI:

:- dynamic s/1.

foo --> "hello",   { retractall(s(_)), asserta(s(hi))  }.
foo --> "goodbye", { retractall(s(_)), asserta(s(bye)) }.

For example:

?- s(X).
false.

?- phrase(foo, "hello").
true .

?- phrase(foo, "hello").
true ;
false.

?- s(X).
X = hi.

?- phrase(foo, "goodbye").
true.

?- s(X).
X = bye.

I'm curious why you're doing this though. My inclination, all things being equal, would be to augment the AST you're generating with the information you're asserting. Then again, I'm biased against the dynamic store.

Daniel Lyons
  • 22,421
  • 2
  • 50
  • 77
  • Thank you for answering.I'm a newbie when it comes to prolog: what do you mean by AST? – macguy Feb 25 '13 at 01:01
  • Abstract Syntax Tree. What I'm really saying is that when you parse text, the idea is to reconstruct some kind of structure, and that structure is the result of the parse. Using `assert` and `retract` from within the parsing process is a side-effect. Knowing nothing else, I would in general rather have the result of a parse be completely contained within the structure, and then have an evaluator that handles the side effects. – Daniel Lyons Feb 25 '13 at 05:07
1

I don't completely understand your code but I have a feeling that this:

v(0.65, v(put)) --> {retract(s(V, NP))}, [put].

v(0.35, v(take)) --> {retract(s(V, NP, PP))}, [take].

should be:

v(0.65, v(put)) --> [put], {retract(s(V, NP))}.

v(0.35, v(take)) --> [take], {retract(s(V, NP, PP))}.

However, why are the V, NP, PP non-instantiated? If you want to remove all the occurrences you should use retractall/1; if there is only one occurrence I suggest using swipl's global variables. In any case, by using side effects in a DCG is like a deal with the devil; I did it in my compiler and it was a debuging hell XD

Thanos Tintinidis
  • 5,828
  • 1
  • 20
  • 31
  • I edited my question and posted the whole code, what I'm trying to do is delete the grammar Rule S ---> V NP PP if the input verb is take, and delete the grammar rule S ---> V NP if the input verb is put. – macguy Feb 25 '13 at 01:07
1

Here's what I ended up doing, I used constraints to choose a certain rule over another: And here is the code:

s(P0, s(V, NP)) --> v(P1, V), np(P2, NP), {P0 is P1*P2*0.35, V == v(take)}.
s(P0, s(V, NP, PP)) --> v(P1, V), np(P2, NP), pp(P3, PP), {P0 is P1*P2*P3*0.65, V == v(put)}.

np(P0, np(D, N)) --> det(P1, D), n(P2, N), {P0 is P1*P2*0.36}.
np(P0, np(D, A, N)) --> det(P1, D), a(P2, A), n(P3, N), {P0 is P1*P2*P3*0.46}.
np(P0, np(D, N, PP)) --> det(P1, D), n(P2, N), pp(P3, PP), {P0 is P1*P2*P3*0.13}.
np(P0, np(D, A, N, PP)) --> det(P1, D), a(P2, A), n(P3, N), pp(P4, PP), {P0 is P1*P2*P3*P4*0.05}.

pp(P0, pp(P, NP)) --> p(P1, P), np(P2, NP), {P0 is P1*P2*1.0, NP \= np(_, _ , _, _)}.

v(0.65, v(put)) --> [put].
v(0.35, v(take)) --> [take].

n(0.23, n(block)) --> [block].
n(0.25, n(circle)) --> [circle].
n(0.15, n(cone)) --> [cone].
n(0.12, n(cube)) --> [cube].
n(0.25, n(square)) --> [square].

a(0.56, a(blue)) --> [blue].
a(0.27, a(green)) --> [green].
a(0.17, a(red)) --> [red].

det(1.0, det(the)) --> [the].

p(1.0, p(on)) --> [on].
macguy
  • 294
  • 3
  • 12