Это довольно неприглядное, насколько модели данных идут и все, что вы пытаетесь сделать с этим собирается по крайней мере быть неэффективным, если он может даже заставить работать. Вам было бы намного лучше определить факт arity 3 с первым arg, являющимся атомом, который идентифицирует тип.
При этом вы, вероятно, можете сделать достаточно интроспекции, чтобы справиться с этим.
dif(Q, P),
predicate_property(QR, dynamic),
predicate_property(PR, dynamic),
QR =.. [Q, _, _],
PR =.. [P, _, _].
Это говорит о том, что я нашел два предиката с арностью 2, головы которых разные. В идеале вам нужны только определенные пользователем предикаты. SWI-Prolog не может это сделать, но GNU Prolog может, вы могли бы добавить некоторые дополнительные ограничения:
predicate_property(QR, user),
predicate_property(PR, user),
Это мое решение:
matching(Q, P) :-
dif(Q, P), % different predicates, please
predicate_property(QR, dynamic), % both dynamic
predicate_property(PR, dynamic),
QR =.. [Q, Q1, Q2], % arity-2 predicates, please
PR =.. [P, P1, P2],
findall([Q1, Q2], clause(QR, true), Qs), % find all facts (:- true)
findall([P1, P2], clause(PR, true), Ps),
forall(member(PV, Ps), member(PV, Qs)), % ensure the fact sets are equal
forall(member(QV, Qs), member(QV, Ps)).
Пожалуйста, пожалуйста, пожалуйстаНЕ ДЕЛАТЬ ЭТО !
Что вы подразумеваете под * динамическим *? Вы имеете в виду динамический факт базы данных, который вы утверждаете или убираете в ходе своей программы? 'D1 (_, _)' не является списком, поэтому 'member (E, D1 (_, _))' не имеет никакого смысла. Кроме того, 'D1' и' D2' являются переменными, так как они начинаются с заглавной буквы. Вы предполагали, что это атомы ('d1' и' d2')? У вас не может быть факта или предиката с переменной для имени, например 'D1 (...)'. – lurker