Error unknown procedure parent 2 dwim could not correct goal

Ошибка при каждой компиляции Prolog Решение и ответ на вопрос 603112

grafrh

0 / 0 / 0

Регистрация: 11.06.2012

Сообщений: 3

1

Ошибка при каждой компиляции

11.06.2012, 22:19. Показов 1946. Ответов 5

Метки нет (Все метки)


Заранее извиняюсь за банальный вопрос, но только сегодня открыл мануал по Prolog, а FAQ на форуме я не нашёл.
Суть в том что я пишу код вида

Prolog
1
2
parent(bob, stan).
?-parent(bob,stan).

При компиляции Visual Prolog выдаёт ошибку. И что характерно, это всегда ошибка в первой строке, первой букве. В чём проблема?
Может быть я чего нибудь не дописал? Не там написал или ещё чего? Большая просьба, если меня куда то и посылать, то в сторону годного мануала по Visual Prolog 7.3. Опыт в программировании почти нулевой. Заранее спасибо.

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Грымзик

2505 / 1479 / 37

Регистрация: 14.09.2009

Сообщений: 2,740

11.06.2012, 23:50

2

В визуал 7.3 другой синтаксис. Там будет как-то так

Prolog
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
implement main
    open core, console
 
constants
    className = "main".
    classVersion = "".
 
class facts
    parent:(string,string).
    
class predicates
    is_parent:(string,string) procedure(i,i).
    
clauses
    classInfo(className, classVersion).
    
    parent("bob","stan").
   
    is_parent(A,B):-parent(A,B),!,write(A," is a parent of ",B,"n").
    is_parent(A,B):-write(A," is not a parent of ",B,"n").
    
    run():-
        console::init(),
        is_parent("bob","stan"),
        programControl::sleep(3000),
        succeed().
end implement main
 
goal
    mainExe::run(main::run).



1



0 / 0 / 0

Регистрация: 11.06.2012

Сообщений: 3

12.06.2012, 14:29

 [ТС]

3

Грымзик, спасибо, всё становится яснее.
Сейчас читаю официальный мануал по VIP и пытаюсь вкурить что и куда.
Ещё вопрос. А как будет выглядеть та же задача на SWI-Prolog?



0



2505 / 1479 / 37

Регистрация: 14.09.2009

Сообщений: 2,740

12.06.2012, 14:43

4

Как Вы и написали) Точнее код просто parent(bob, stan), а ?-parent(bob,stan) вызывается в командной строке.



1



grafrh

0 / 0 / 0

Регистрация: 11.06.2012

Сообщений: 3

12.06.2012, 17:16

 [ТС]

5

Грымзик, Выглядит намного проще )
Но при вводе

Prolog
1
parent(bob,stan).

выдаёт следующую ошибку ERROR: toplevel: Undefined procedure: parent/2 (DWIM could not correct goal)
Конечно я уже начал курить хелп, но думаю совет мне не помешает.



0



2505 / 1479 / 37

Регистрация: 14.09.2009

Сообщений: 2,740

12.06.2012, 17:20

6

Вы не скомпили файл.



1



Возможность модифицировать базу знаний в процессе выполнения программы на Прологе позволяет описывать логику систем, изменяющихся в реальном времени. Рассмотрим основные предикаты для работы с базой знаний.

В качестве примера будем использовать простейшую программу.


:-dynamic p/2.
p(1,a).
p(2,b).
q(X,Y):-p(Y,X).
r(123).


Предикат dynamic в первой строке указывает интерпретатору на то, что определение двуместного предиката p может изменяться в процессе выполнения (с помощью предикатов assert и retract). Для многопоточных программ это так же означает, что предикат будет общим для всех потоков.

  1. clause(:Head, ?Body)
    Предикат clause истинен, если в базе знаний имеется предикат, голова которого унифицируется с Head, а тело — с Body. Для фактов Body унифицируется с атомом true. Например:


    ?- clause(q(a,b),p(b,a)).
    true

    ?- clause(q(a,b),p(b,b)).
    false

    ?- clause(r(_),true).
    true.


    Предикат clause может применяться для поиска возможных конъюнкций целей, из истинности которых будет следовать истинность цели, голова которой унифицируется с Head. Например:


    ?- clause(q(X1,X2),Z).
    Z = p(X2, X1).


    Полученный ответ означает, что для доказательства цели q(X1,X2) нужно доказать цель p(X2,X1). Заметим, что аргумент Head предиката clause должен быть обязательно конкретизирован, то есть мы не можем по телу предиката найти его голову:


    ?- clause(X,p(b,a)).
    ERROR: clause/2: Arguments are not sufficiently instantiated


    Удобно использовать предикат clause для проверки существования в базе знаний предиката, голова которого унифицируется с Head:


    ?- clause(p(_,_),_).
    true ;
    true.

    ?- clause(s(_,_),_).
    false.


  2. retract(+Term)
    Удаляет из базы знаний первый факт или предложение, унифицируемое с Term. Предикат, предложение которого удаляется, должен быть динамическим. Пример:


    ?- p(X,Y).
    X = 1,
    Y = a ;
    X = 2,
    Y = b.

    ?- retract(p(X,Y)).
    X = 1,
    Y = a .

    ?- p(X,Y).
    X = 2,
    Y = b.


  3. retractall(+Term)
    Удаляет из базы знаний все факты и предложения, унифицируемые с Term. Предикат, предложения которого удаляются, должен быть динамическим. Пример:


    ?- p(X,Y).
    X = 1,
    Y = a ;
    X = 2,
    Y = b.

    ?- retractall(p(X,Y)).
    true.

    ?- p(X,Y).
    false.


    Если Term соответствует предикату, не определенному в базе знаний, то он автоматически создается как динамический предикат (retract не обладает этим свойством):


    ?- new_predicate(X).
    ERROR: toplevel: Undefined procedure: new_predicate /1 (DWIM could not correct goal)

    ?- retractall(new_predicate(X)).
    true.

    ?- new_predicate(X).
    false.


  4. abolish(:PredicateIndicator)
    Удаляет все предложения предиката с заданным функтором и арностью. PredicateIndicator указывается в виде <функтор>/<арность>. В отличие от retractall позволяет удалять предложения статических предикатов:


    ?- q(a,1).
    true.

    ?- retractall(q(X,Y)).
    ERROR: retractall/1: No permission to modify static_procedure `q/2'

    ?- q(a,1).
    true.

    ?- abolish(q/2).
    true.

    ?- q(a,1).
    ERROR: toplevel: Undefined procedure: q/2 (DWIM could not correct goal)


  5. assert(+Term)
    asserta(+Term)
    assertz(+Term)
    Добавляют факты и предложения в базу знаний. Предикаты assert и assertz эквивалентны и добавляют факт/предложение в конец списка фактов и предложений для соответствующего им предиката, а предикат assertа добавляет в начало списка. Пример использования:


    ?- p(X,Y).
    X = 1,
    Y = a ;
    X = 2,
    Y = b.

    ?- asserta(p(0,c)).
    true.

    ?- assert(p(3,d)).
    true.

    ?- p(X,Y).
    X = 0,
    Y = c ;
    X = 1,
    Y = a ;
    X = 2,
    Y = b ;
    X = 3,
    Y = d.


Итак, мы рассмотрели все основные предикаты для управления базой знаний в логических программах на Прологе.

Вопрос:

Просто установил SWI-Prolog на моей машине W8, и он выдал ошибку.

Здесь ошибка:

ERROR: toplevel: Undefined procedure: mark/0 (DWIM could not correct goal)

Скажем, мой исходный файл пролога содержит один факт:

 Prolog source...

it_is_monday.   //The fact

Поэтому я скомпилирую буфер и получаю:

.../documents/prolog/prologSource compiled 0.00 sec, 2 clauses

Теперь, когда я ввожу

it_is_monday.

Результат, как и ожидалось, true. Однако, когда я ввожу слово,

some_other_statement.

Я получаю сообщение об ошибке выше, а не false. Может ли кто-нибудь сказать мне, что здесь происходит?

Решение: Разная версия пролога.

Лучший ответ:

Там стандартный Пролог флаг, unknown, что по умолчанию устанавливается в SWI-Prolog и других современных компиляторов Пролога к error, а это означает, что попытка вызвать неизвестный предикат приведет к исключению. Этот флаг может быть установлен (с использованием стандартного предиката set_prolog_flag/2) вместо того, чтобы fail получить поведение, которое вы, похоже, ожидаете, но которое не рекомендуется, поскольку это может затруднить отладку. Например, просто опечатка в имени предиката приведет к сбою, который в сложной программе может быть трудно отследить, в то время как ошибка существования предиката будет выявлять виновника на месте.

Ответ №1

Вы получаете ошибку

ERROR: toplevel: Undefined procedure: mark/0 (DWIM could not correct goal)

потому что вы не определили процедуру, которую вы пытались выполнить. (почему он говорит undefined)

Если вы его определите, отредактируйте файл .pl и some_other_statement.

и вы запустите его снова, вы получите

1 ?- some_other_statement.
true.

В Prolog вам нужно определить каждую процедуру, которую вы хотите выполнить.

Когда вы пытаетесь выполнить неопределенную процедуру, в процедуре будет отображаться имя процедуры. Итак, если вы еще не определили some_other_statement. , ошибка будет:

2 ?-  some_other_statement.
ERROR: toplevel: Undefined procedure: some_other_statement/0 (DWIM could not correct goal)

обратите внимание, что some_other_statement/0 отображается на ошибке, которую я получил.

EDIT: Если вы хотите получить false сообщение, вам нужно будет определить что-то вроде some_other_statement(1). а затем выполните запрос типа some_other_statement(12).

2 ?- some_other_statement(12).
false.

Ответ №2

если вы хотите получить ложь от этого, вы можете добавить директиву

:- dynamic(some_other_statement/0).

в начале файла, поэтому, когда вы выполняете запрос

?- some_other_statement.

вы получите ложное

In the code snippet you show, the only thing that wouldn’t «work» is the X^intr(Y) in the body of the first of the two rules. The X^Y in the head should «work» if ^ is defined as an operator. Here is what I see:

$ swipl
Welcome to SWI-Prolog (threaded, 64 bits, version 8.1.15-10-g6718ecfeb)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.

For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).

?- current_op(Precedence, Type, ^).
Precedence = 200,
Type = xfy.

?- display(a^b).
^(a,b)
true.

To show that you can indeed have X^Y in the head:

?- [user].
|: intr(X^Y) :- format("Got `intr(~w^~w)`~n", [X, Y]).
|: ^D% user://1 compiled 0.02 sec, 1 clauses
true.

?- intr(a^b).
Got `intr(a^b)`
true.

But I don’t understand what you want the body of that rule to do. I also couldn’t easily define a callable ^/2. Here is what I tried and what I got:

?- [user].
|: X^Y :- format("Evaluating `~w^~w` as a goal~n", [X, Y]).
|: ^D% user://2 compiled 0.02 sec, 1 clauses
true. % <---- seems to work? but not really

?- a^b.
ERROR: Unknown procedure: b/0 (DWIM could not correct goal)
?- X^B.
ERROR: Unknown procedure: '$toplevel':(^)/2
ERROR:   ^/2 can only appear as the 2nd argument of setof/3 and bagof/3
ERROR: In:
ERROR:   [10] '$toplevel':_12658^(user:_12666)
ERROR:    [9] <user>
   Exception: (10) _11996^(user:_11998) ? creep

PS: Warning: personal opinion!

I prefer to not redefine operators or built-in predicates. It looks nice and you can definitely do nifty stuff (like your own DSL that «just works» on the top level). But if you give such code to others, it becomes a difficult exercise. In my personal experience, I have found it much easier to first parse whatever I have into something that is valid Prolog, with the default operators only. What I mean in practice is something along these lines:

?- [user].
|: foo(A^B) :- hat(A, B).
|: hat(A, B) :- format("Evaluating ~w^~w~n", [A, B]).
|: ^D% user://1 compiled 0.03 sec, 2 clauses
true.

?- foo(a^b).
Evaluating a^b
true.

Nitpicking now, but in the original code you show, I don’t think you need the cuts.

Понравилась статья? Поделить с друзьями:
  • Error unexpected mutation of prop vue no mutating props
  • Error unexpected end of file radmir
  • Error uncaught rangeerror webassembly memory could not allocate memory
  • Error unauthorized authentication required docker
  • Failed to execute script get как исправить