2015-03-04 2 views
2

Учитывая следующие факты: ПрологРекурсия в PROLOG?

f(a, [b]). 
f(b, [c]). 
f(c, [d]). 
f(d, [e]). 
f(e, []). 

Мне нужно создать запрос xyz(a,Y), так что я получаю Y = [e,d,c,b], так как зависит от Ь, зависящей от с и т.д. Мой текущий запрос:

xyz(X,Y):- 
    f(X,P), 
    member(Y,[P]). 

Однако этот запрос для xyz(a,Y) только дает мне Y = [b], а не иждивенцев б и т.д.

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

f(P,S), 
member(Y,[P]). 

Я уверен, что в конце я должен добавить рекурсию, но я не уверен, как подойти. Может кто-то мне помочь, пожалуйста?

(3/4) Edit:

мне удалось успешно решить проблему списков одноэлементных с @CapelliC захода на посадку ниже. Тем не менее, я хотел бы расширить эту проблему так, что она работает для списков многоэлементных, где факты Пролога выглядеть как:

f(a, [b, d]). 
f(b, [c]). 
f(c, []). 
f(d, [e]). 
f(e, [f]). 
f(f, [g). 
f(g, []). 

В этом случае запрос о xyz(a,X) должен дать мне: X = [b,c,d,e,f,g], в элемент- порядок не обязательно имеет значение, я могу сортировать его после.

Это был предыдущий код, который работает для отдельных списков:

xyz(Z, [X|Y]):- 
    f(Z,[X]), 
    !, 
    xyz(X,Y). 
    xyz(_,[]). 

Согласно @lurker мне нужно включить функцию-член, но у меня возникли проблемы с ним. Это мой текущий подход, но он не работает, а только дает мне пустой список в качестве вывода для всего:

xyz(Z, [X|Y]):- 
    f(Z,X), 
    member(Y,X), // I'm not sure if this should be a 'Y' 
    !, 
    xyz(X,Y). 
    xyz(_,[]). 

Любые идеи?

+0

Запрос 'f (X, P, _)' всегда будет терпеть неудачу, потому что он не соответствует артерии ваших фактов 'f', которые имеют два аргумента. Поэтому я не вижу, как ваш текущий 'xyz (a, Y)' преуспевает. Проверьте наличие типографских ошибок в том, что вы показываете. – lurker

+0

@lurker Извините. Я обновлю свой пост. Я с нетерпением жду вашего ответа, спасибо. – am3decoy

+0

Если 'P' - это уже список, вы не хотите' member (Y, [P]) '. Вы хотите 'member (Y, P)'. Например, если 'P = [a, b, c]', то 'member (Y, [P])' истинно *, только если * 'Y = [[a, b, c]]'. Не то, что вы хотите. Если вы выполняете 'member (Y, P)', то это верно для 'Y = a' или' Y = b' или 'Y = c'. – lurker

ответ

1

этот фрагмент получить список в обратном порядке, WRT ваш запрос ...

xyz(K, [D|Ds]) :- f(K, [D]), !, xyz(D, Ds). 
xyz(_, []). 

редактировать простирающийся на несколько элементов зависимостей (но без петель!) Может быть сделано как

xyz(K, Ds) :- f(K, DKs) -> findall([T|P], (member(T, DKs), xyz(T, P)), L), flatten(L, F), sort(F, Ds) ; Ds = []. 
+0

спасибо, я изучу ваш подход. Из-за этого мне удалось обнаружить идею «порезов», чтобы контролировать откат. Также я не знал, что у вас может быть несколько выражений, заканчивающихся на. в одном условном предикате. Кстати, мне не нужен фрагмент в обратном порядке. Быстрый способ исправить это? – am3decoy

+0

Кроме того, я заметил, что даже если это работает для большинства тестовых сценариев, оно не работает для всех и дает пустой список вместо правильного списка ответов. Например, учитывая эти факты Пролога: «f (a, [b, c, d]). F (b, [e]). F (c, [j, g]). F (d, [c, g ]). f (e, [h]). f (g, [b]). f (j, [b]). f (h, []). и с вашим подходом, xyz (a, X), я получаю X = [], когда я должен получить плотный список. Знаете ли вы, есть ли какие-то определенные ограничения, которые могут быть в вашем коде, которые вызывают это? Спасибо. – am3decoy

+0

@ am3decoy Ваше оригинальное заявление о проблеме показало все одноэлементные списки для ваших фактов. Вы отметили только многоэлементные списки в своем комментарии. Поэтому ваш оригинальный вопрос очень неясен. – lurker

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