2014-12-09 4 views
-1

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

Я продолжаю думать о процедурной логике и не могу по-настоящему обвести ее вокруг себя. Это то, что я имеет смысл для меня, - но это не работает ...

//KB 
r([a|X],Y,[gone|X]). 
r([c|X],Y,[gone|X]). 
r([b|X],Y,[known|X]). 
r([d|X],Y,[known2|X]). 

simplify([X|List],[X|NW],Result) :- 
    r(List,Nw,NewList), 
    !, 
    simplify2(NewList,Nw,Result). 

simplify2([W|Words],Nw,[W|NewWords]) :- 
    simplify2(Words,Nw,NewWords). 

simplify2([],[],[]). 

Запрос:

- упростить ([а, Ь, с, d, е, е], X , Y).

Я хочу:

X = [e,f] 
Y = [gone,known,gone,known2] 

но выше дает X = [a|mem_address] и Y = [d,e].

+0

Очень загадочный. Я понимаю, что X - это «неизвестные» элементы. Но что такое Y? –

+0

Btw, мне любопытно, как у вас есть адрес памяти, как хвост списка Prolog! –

+0

Eugene, X неизвестен и Y известен! Я хочу упростить (перевести) известные термины и удалить известные термины шума и оставить список известных терминов, с которыми я могу что-то сделать, и отдельный список неопубликованных терминов, которые я могу «изучить». – Conor

ответ

0

Ну, сначала вам нужно собрать данные из КБ (фактически, общий термин - База данных), используя setof. И тогда это просто:

r([a|X],Y,[gone|X]). 
r([c|X],Y,[gone|X]). 
r([b|X],Y,[known|X]). 
r([d|X],Y,[known2|X]). 

kb(L) :- setof((A,B), r([A|_],_,[B|_]), L). 

simplify([], [], []). 
simplify([H|T], T1, [H2|T2]) :- 
    kb(L), 
    member((H,H2), L), 
    simplify(T, T1, T2). 

simplify([H|T], [H|T1], T2) :- 
    simplify(T, T1, T2). 
+0

Это дает все возможные списки. – false

+0

Это хороший пример ошибки, трассировщик может показать вам не менее прямой, чем чистый взгляд на программу. Или попробуйте цель на верхнем уровне. – false

+0

Спасибо, Евгений, это имеет большой смысл, и я использую тот тип mathod - я должен был быть более ясным и сказал, что [ушел | X] на самом деле просто X. go удален! Но я должен быть в состоянии настроить это на основе вашей помощи. Действительно, спасибо большое – Conor

1

Давайте сначала исправить синтаксис:

  • Rest-оф-лайн комментарий в Прологе начинается с % не //.
  • Удалить второй аргумент из r/3; это не имеет целью.
  • MW ->Mw в simplify/3.
  • Вставка пробелов между аргументами (не синтаксически некорректная, но немного сложная для чтения).

Теперь давайте удалим некоторые увольнения:

  • В r/2 вы на самом деле не нужны список хвосты.
  • Кроме того, нам не нужен список, чтобы указать, что какой-то термин «известен» или «ушел».
  • simplify/3 и simplify2/3 могут быть объединены в один и тот же предикат.

Теперь давайте добавим некоторые новые вещи:

  • Объявить r/2 в динамический. Это позволяет изменять KB с использованием assert/1 и retract/1.
  • Использовать согласованное присвоение имен для переменных. Например, H для заголовка списка, T для списка tail и L для (полного) списка.

Мы получаем следующее:

:- dynamic(r/2). 

r(a, gone). 
r(c, gone). 
r(b, known). 
r(d, known2). 

simplify([], [], []). 
simplify([H|T1], L2, L3):- 
    ( r(H, Status) 
    -> L2 = T2, 
     L3 = [Status|T3] 
    ; L2 = [H|T2], 
     L3 = T3 
), 
    simplify(T1, T2, T3). 

С желаемого поведения:

?- simplify([a,b,c,d,e,f],X,Y). 
X = [e, f], 
Y = [gone, known, gone, known2]. 

Обратите внимание, как в приведенном выше я выполнил следующие действия:

  1. я стараюсь для получения синтаксически допустимого Prolog.
  2. Как только программа имеет действительный синтаксис, я пытаюсь упростить ее, сохраняя стабильное/неповрежденное поведение.
  3. Только, когда код является синтаксически действительным и упрощенным, я начинаю изменять его, чтобы достичь намеченного поведения.

Edit: Благодаря false для указания на не-пристальном поведения. Программа была отредактирована соответствующим образом.

+0

@false Действительно! Я был очень удивлен тем, что запрос выполнил следующее :-(Есть ли способы проверить устойчивость в алгоритме и/или систематически? (Я знаю, что есть некоторые статьи по этому вопросу, но они довольно формальные.) –

+1

@false [Lau et al., 1999 ] (http://ac.els-cdn.com/S0743106698100237/1-s2.0-S0743106698100237-main.pdf?_tid=9bbbcfac-7fee-11e4-b931-00000aacb35e&acdnat=1418162532_90275649a1ebe44eb1f4c5e46a007ab5) находится в моем списке для чтения, но мне потребуется некоторое время, чтобы пахать, я боюсь. –

+0

Спасибо, я просто просматриваю примеры: Определенно, какая-то стойкость немного отличается. На самом деле. сноска 3 Обратите внимание, что то, что мы называем «стойким» логическая программа "полностью отличается от того, что O'Keefe ([33], стр. 96) называет« стойким предикатом », хотя мы также (нужно) использовать« стойкий »в смысле« неизменный ». – false

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