Как я могу динамически утверждать правила с условиями, соединенными в теле в Прологе? - PullRequest
1 голос
/ 01 ноября 2019

Мой код:

run_insert_format([]).
run_insert_format([H|T]) :- H = [X,Y],
                            assertz(( X :- (verificar(Y)) )), run_insert_format(T).

run_query :- 
    odbc_query(
        bd,
        sqlQueryString,
        List,
        [ findall([Animal,Characteristic],row(Animal,Characteristic)) ]),
        run_insert_format(List).

Переменная List дает мне что-то вроде этого:

[ [chita, mamifero], [chita, carnivoro], [chita, color_rojizo] ]

Я пытаюсь получить это какрезультат asssertz:

%Reglas (rules)
% chita :-
%     verificar(mamifero),
%     verificar(carnivoro),
%     verificar(color_rojizo).

Но вместо этого я получаю это:

% chita :-
%     verificar(mamifero).
% chita :-
%     verificar(carnivoro).
% chita :-
%     verificar(color_rojizo).

Я знаю, что код делает правильно, но что я могу сделать, чтобы получить второерезультат?.

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

1 Ответ

1 голос
/ 01 ноября 2019

Чтобы сформулировать проблему, для каждой головы foo вы устанавливаете условие для каждого условия f1, f2, т. Е.

foo :- f1.
foo :- f2.

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

foo :- f1, f2.

Ключевой шаг, который вам не хватает, - это преобразование набора характеристик для каждого животного в соединение, которое затем можно утверждать как тело.

Вот один из способов достижения этого результата, используя swi-prolog списки ассоциаций для группировки признаков:

:- use_module(library(assoc)).

assert_characteristics(Characteristics) :-
    group_characteristics(Characteristics, GroupedCharacteristics),
    maplist(assert_condition, GroupedCharacteristics).

% Conditions should be a conjunction, e.g., `(a, b, c)`
assert_condition(Head-Conditions) :-
    maplist(make_check, Conditions, Checks),
    list_to_conjunction(Checks, Conjunctions),
    assertz(( Head :- Conjunctions )).

% ex. group_characteristics([foo-f1, foo-f2, bar-b1], [foo-[f1,f2], bar-[b1]]).
group_characteristics(AnimalCharacteristics, Grouped) :-
    empty_assoc(Assoc),
    group_characteristics(AnimalCharacteristics, Assoc, Grouped).

% helper for group_characteristics/2
group_characteristics([], Assoc, Grouped) :- assoc_to_list(Assoc, Grouped).
group_characteristics([Animal-Char|Rest], Assoc0, Grouped) :-
    % Updating an existing animal with the new characteristic `Char`
    ( get_assoc(Animal, Assoc0, Chars, Assoc1, [Char|Chars]), !
    % Otherwise, the key for `Animal` isn't present yet, so add it.
    ; put_assoc(Animal, Assoc0, [Char], Assoc1) ),
    group_characteristics(Rest, Assoc1, Grouped).


% Convert a list of predictes into a conjunction of predicates
% ex. list_to_conjunction([a,b,c], (a, (b, (c, true)))).
list_to_conjunction([], true).
list_to_conjunction([P|Ps], (P, Conjuncts)) :- list_to_conjunction(Ps, Conjuncts).

% just a helper used in assert_condition/1
make_check(C, verificar(C)).

Пример использования:

?- assert_characteristics([foo-foo1, bar-bar1, foo-foo2]).
true.

?- listing(foo).
:- dynamic foo/0.

foo :-
    verificar(foo2),
    verificar(foo1),
    true.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...