Пролог на основе правил системы - PullRequest
1 голос
/ 04 апреля 2011

Привет, у меня есть система прологов, основанная на правилах, как показано ниже:

%forward chaining Production system
:-op(800,fx,if).        %set operators for if
:-op(700,xfx,then).     %then rules
:-op(300,xfy,or).
:-op(200,xfy,and).


%dynamic(....) allows predicate inside brackets fact to be asserted and retracted,
% here were are making fact (/1 means fact has 1 argument) dynamic so we can add and
% take facts from working memory.

:-dynamic(fact/1).

fact(has(smith,raisedIntraocularPressure)).        %list of facts
fact(had(smith,previousHeatAttack)).
fact(has(smith,leftQuadraticPain)).
fact(is(smith,heavySmoker)).
fact(is(jones,asthmatic)).
fact(has(jones,raisedIntraocularPressure)).
fact(is(jones,heavySmoker)).

forward:-
  new_fact(P),
  !,
  write('New fact '), write(P),nl,
  asserta(fact(P)),                        %adds a fact to working memory
  forward
;
  write('no more facts').


new_fact(Action):-
  if Condition then Action,
  not(fact(Action)),
  composedFact(Condition).

composedFact(Cond):-
  fact(Cond).

composedFact(C1 and C2):-
  composedFact(C1),
  composedFact(C2).

composedFact(C1 or C2):-
  composedFact(C1)
;
  composedFact(C2).


print:-


if has(Person,riskOfHeartAttack) and has(Person,previousHeartAttack)
then need(Person,digitalis).
if has(Person,leftQuadraticPain) and has(Person,highBloodPressure)
then has(Person,riskOfHeartAttack).
if has(Person,leftQuadraticPain)then has(Person,highBloodPressure).
if has(Person,highBloodPressure) and is(Person,heavySmoker)
then has(Person,riskOfHeartAttack).
if is(Person,asthmatic) and has(Person,riskOfHeartAttack) and has(Person,previousHeatAttack)then give(Person,preminolv).

not(X):-
 X,!,fail;true.

Хорошо, сначала мне нужно создать команду, которая печатает список фактов в базах данных.

Во-вторых, каждое правило используется только один раз.Мне нужно изменить код, чтобы использовать все соответствующие факты.По-видимому, это можно сделать с помощью функции «bagof», но я понятия не имею, как ее использовать.

Заранее спасибо = D

1 Ответ

2 голосов
/ 04 апреля 2011

Распечатать список фактов:

print_facts :-
    findall(F, fact(F), Facts),
    maplist(writeln, Facts).

Метапредикат findall/3 также является ключом ко второму вопросу, хотя вы также можете использовать bagof. См. документацию , учебник .

...