Ошибка визуального пролога c502: выражение не дает значения
Я пытаюсь перевести простую проблему Turbo Prolog в Visual Prolog 7.1
Оригинальный код Turbo Prolog следующий.
DOMAINS
s=string sl=s* sll=sl*
PREDICATES
select(sl,s,sl)
solve(sll)
CLAUSES
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
solve([["Anna",A,A],["Kate",Vp,Vt], ["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
И его результирующий список выводится с solve(Out)
с обеспечивает правильный результат для консоли Turbo Prolog.
При попытке перевести это в Visual Prolog, я получаю ошибку c502 в строке 33.
implement main
open core
constants
className = "main".
classVersion = "".
domains
s=string.
sl=s*.
sll=sl*.
%
class predicates
select:(sl,s,sl) nondeterm anyflow.
solve:(sll) nondeterm anyflow.
%
clauses
%
select([A|B],A,B).
select([A|B],C,[A|D]):- select(B,C,D).
%
solve([["Anna",A,A],["Kate",Vp,Vt],["Natasha",Np,"green"]]):-
select(["white","green","blue"],A,ColPl),
select(["white","blue"],A,[Vt]), Vt<>"white",
select(ColPl,Vp,[Np]), Vp<>"white", Np<>"green".
clauses
classInfo(className, classVersion).
clauses
run():-
console::init(),
%ERROR AFTER THIS LINE
stdIO::writef("%", solve(Out)),fail().
end implement main
goal
mainExe::run(main::run).
Что я получаю от этой ошибки, так это то, что solve(Out)
не дает ничего печатать. Чего я не знаю, так это как изменить код, чтобы создать что-то для печати.
Я новичок в Прологе, и я не могу понять, как решить эту проблему, и Google тоже не очень помогает, кажется, это очень непонятная проблема.
Спасибо!
1 ответ
Я не знаком с Visual Prolog, но не могли бы вы переписать оскорбительную строку следующим образом:
solve(Out), stdIO::writef("%", Out),fail().
и попробуй еще раз?
Помните, что предикаты не являются функциями, как в других языках программирования; они не имеют возвращаемого значения.
РЕДАКТИРОВАТЬ, чтобы ответить на комментарий: предикат процедуры должен завершиться ровно один раз. Вот, main
зовет ваш solve
функция, которая может быть неудачной или успешной несколько раз. Чтобы убедиться в этом, вы можете попытаться заключить вызов для решения в другой предикат:
wrap_solve(S) :- solve(S), !.
wrap_solve([]).
Разрез после звонка solve
следует убедиться, что вы получите только одно решение, если это удастся. Если нет решения (например, вызов solve
терпит неудачу), тогда второе предложение даст значение по умолчанию (пустой список в этом случае).
В main
позвони wrap_solve
вместо solve
,