Пролог решает определенное правило для выбора в зависимости от ввода
У меня проблема с прологом, которую я не могу обойти. То, чего я пытаюсь добиться, - это утвердить ФАКТ А, убрать Факт B, когда у меня есть ввод: взять и утвердить Факт Б и убрать Факт А, когда у меня есть ввод пут.
то есть:
:- 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].
Я не могу заставить его работать: любая помощь будет оценена.
РЕДАКТИРОВАТЬ: ВСЕ КОД РАЗМЕЩЕН
3 ответа
Вот что я в итоге сделал, я использовал ограничения, чтобы выбрать одно правило вместо другого: А вот код:
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].
Я не совсем понимаю ваш код, но у меня есть ощущение, что это:
v(0.65, v(put)) --> {retract(s(V, NP))}, [put].
v(0.35, v(take)) --> {retract(s(V, NP, PP))}, [take].
должно быть:
v(0.65, v(put)) --> [put], {retract(s(V, NP))}.
v(0.35, v(take)) --> [take], {retract(s(V, NP, PP))}.
Тем не менее, почему V
, NP
, PP
без инстанцирован? Если вы хотите удалить все вхождения, вы должны использовать retractall/1
; если есть только один случай, я предлагаю использовать глобальные переменные swipl. В любом случае, использование побочных эффектов в DCG похоже на сделку с дьяволом; Я сделал это в моем компиляторе, и это был отладочный ад XD
Я подозреваю, что проблема лежит в другом месте в вашем коде. Это сработало для меня с SWI:
:- dynamic s/1.
foo --> "hello", { retractall(s(_)), asserta(s(hi)) }.
foo --> "goodbye", { retractall(s(_)), asserta(s(bye)) }.
Например:
?- s(X).
false.
?- phrase(foo, "hello").
true .
?- phrase(foo, "hello").
true ;
false.
?- s(X).
X = hi.
?- phrase(foo, "goodbye").
true.
?- s(X).
X = bye.
Мне любопытно, почему ты это делаешь. Моя склонность, при прочих равных условиях, заключалась бы в увеличении AST, который вы генерируете, информацией, которую вы утверждаете. Опять же, я настроен против динамического магазина.