Pull to refresh

Работа с базой знаний в Прологе

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

В качестве примера будем использовать простейшую программу.
:-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.



Итак, мы рассмотрели все основные предикаты для управления базой знаний в логических программах на Прологе.
Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.