Если ваша система Prolog имеет прямой цепной преобразователь, вы можете использовать его для определения циклов. Но будьте осторожны, он может съесть довольно много памяти, поскольку он будет генерировать и хранить path/2
факты.
Вот как вам нужно сформулировать правила в прямом цепочке, который не удаляет автоматически дубликаты. \+
предназначен для явного устранения дубликатов:
:- forward edge/2.
:- forward path/2.
path(X,Y) :- edge(X,Y), \+ path(X,Y).
path(X,Y) :- edge(X,Z), path(Z,Y), \+ path(X,Y).
cycle(X) :- path(X,X).
Чтобы сделать пример немного более интересным в отношении результата, я опустил edge(d,d)
. Вот примерный прогон:
?- postulate(edge(a,b)), postulate(edge(a,c)), postulate(edge(b,a)),
postulate(edge(c,d)), postulate(edge(d,e)), postulate(edge(e,f)),
postulate(edge(f,g)), postulate(edge(g,e)), cycle(X).
X = a ;
X = b ;
X = e ;
X = f ;
X = g
Предикат postulate/1
здесь публикует событие и поддерживает работу пропагатора прямого цепочника. Порядок написания ваших форвардных правил зависит от используемой вами библиотеки Prolog.
П.С .: По-прежнему проводятся исследования:
http://x10.sourceforge.net/documentation/papers/X10Workshop2011/elton_slides.pdf