2016-12-19 5 views
0

Я пытаюсь перевести простую задачу Turbo Prolog на Visual Prolog 7.1Visual Prolog ошибка C502: выражение не дает значение

оригинальный 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 тоже не очень помогает, это кажется очень непонятной проблемой.

Спасибо!

ответ

0

Я не знаком с Visual Prolog, но вы могли бы переписать обижая линию как:

solve(Out), stdIO::writef("%", Out),fail(). 

и попробовать еще раз?

Помните, что предикаты не являются функциями, как на других языках программирования; они не имеют возвращаемого значения.

РЕДАКТИРОВАТЬ ответ: предикат процедуры должен выполняться ровно один раз. Здесь main вызывает вашу функцию solve, которую я терпеть неудачу или преуспевает несколько раз. Для того, чтобы убедиться, что вы можете попытаться обернуть вызов решить в другой предикат:

wrap_solve(S) :- solve(S), !. 
wrap_solve([]). 

Разрез после вызова solve должны убедиться, что вы получите только одно решение, если это удастся. Если нет решения (т. Е. Вызов solve сбой), то второе предложение даст значение по умолчанию (в этом случае будет пустой список).

В main, вы должны позвонить wrap_solve вместо solve.

+0

Благодарим вас за быстрый ответ и исправление моего понимания предикатов! К сожалению, это изменение создает еще одну ошибку: ошибка c631: предикат 'main :: run/0', который объявлен как «процедура», на самом деле «сбой» – Lowry

+0

Возможно, из-за 'fail()' в вашем определение 'main'. –

+0

С этим изменением «отказ» теперь заменяется на «nondeterm» – Lowry

 Смежные вопросы

  • Нет связанных вопросов^_^