2015-03-06 7 views
1

Мне нужна помощь в обратном порядке.Обратный порядок

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

xyz(X, Y):- 
    fun(X, Z) -> findall([A|B], (member(A, Z), xyz(A, B)), L), 
    flatten(L, F), sort(F, Y); Y = []. 

Запрос xyz(a,X). дает мне X = [b,c,d,e,f,g]. Однако, я хотел бы, чтобы дать мне X = [g,f,e,d,c,b].

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

Я попытался добавить дополнительный предикат сразу после этого, но это не сработало:

xyz2(X,Y):- 
    xyz(X,Y), 
    reverse(Y,Z), 
    Z\=0. 

Заслуга CapelliC для подхода к осуществлению выше найденного у меня другой пост здесь. Recursion in PROLOG?

+0

@Boris Обязательно, обновленный оригинал сообщение. Кроме того, я попробовал общий способ сделать это, но, возможно, мне что-то не хватает. Я попытался включить 'reverse (Y, Y)' в конце кода, но это не помогает. – am3decoy

+0

'xyz (X, Y): - f (X, Z) -> findall ([A | B], (член (A, Z), xyz (A, B)), L), flatten (L, F), sort (F, Y); Y = []. (Y, Z), Z \ = 0. Я тоже это пробовал, но чувствую, что мне не хватает важной детали. Я могу использовать только X и Y в качестве аргументов. – am3decoy

+0

@Boris Я обновил сообщение. Возможно, вы можете вести меня в правильном направлении, спасибо. – am3decoy

ответ

2

Вы можете избежать трудного программирования и сделать вашу программу более легкой для чтения, переопределив вашу проблему. Скажем f/2 описывает ориентированный граф, с ребрами из первого аргумента к каждому из элементов второго аргумента, так что:

a ---> b 
a ---> d 
b ---> c 
% etc 

Затем ваш вопрос, какие узлы в графе достижимы из данного узла ? Вы можете определить решение с помощью library(ugraphs).

Для того, чтобы все ребра из f/2:

edge(From-To) :- 
    f(From, L), 
    member(To, L). 

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

foo(X, L) :- 
    findall(E, edge(E), Edges), 
    vertices_edges_to_ugraph([], Edges, G), 
    reachable(X, G, All), 
    once(select(X, All, R)), % remove the node you start from 
    reverse(R, L). 

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

?- foo(a, X). 
X = [g, f, e, d, c, b]. 

?- foo(e, X). 
X = [g, f]. 

?- foo(g, X). 
X = []. 

Я не совсем понимаю, почему порядок элементов значителен. Это немного напоминает запах кода.

+1

Спасибо. Это мой обновленный код, который делает то, что я хотел. xyz (X, Y): - fun (X, Z) -> findall ([A | B], (член (A, Z), xyz (A, B)), L), flatten (L, F) , сортировка (F, Z), обратная (Z, Y); Y = [] .' – am3decoy

+0

@ am3decoy yep это то, что я пытался сказать :) однако этот вопрос и это решение более общие, чем просто обращение вспять списка. –

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