Как сравнить список констант со списком переменных - PullRequest
1 голос
/ 01 мая 2019

Предикат должен сравнивать два списка (один из переменных, один из констант) следующим образом:

?- test([A,B,B],[1,2,3]).
false.

?- test([A,B,B],[1,2,2]).
true.

?- test([A,B,C],[1,2,2]).
false.

Сначала я связываю каждую переменную с ее константой с помощью этого предиката:

set([],[]).
set([X],[Y]):-X is Y.
set([H1|T1],[H2|T2]):-H1 is H2, set(T1,T2).

Он работает для первых двух примеров выше, но не пишет "true". Также не работает для третьего:

?- set([A,B,C],[1,2,2]).
A = 1,
B = C, C = 2

Как я могу изменить этот предикат, чтобы он проверял, использовался ли уже T1, и в этом случае, если он был связан с другой переменной (и, следовательно, возвращает false)?

1 Ответ

1 голос
/ 01 мая 2019

Вы можете добавить dif/2 ограничение между каждыми двумя переменными переменными.

Мы можем получить список переменных с помощью term_variables/2, а затем мы можем, например, разработать предикат all_diff/1, который применяет dif между каждыми двумя различными переменными с помощью используя maplist/2, например:

all_diff([]).
all_diff([H|T]) :-
    maplist(dif(H), T),
    all_diff(T).

Таким образом, мы можем определить наш set/2 как:

set(V, W) :-
    term_variables(V, VV),
    all_diff(VV),
    maplist(is, V, W).

Оригинал set/2 может быть записан как maplist/3 с is/2 в качестве цели.

Например:

?- set([A,B,B], [1,2,2]).
A = 1,
B = 2.

?- set([A,B,C], [1,2,2]).
false.

Если второй список содержит только термины, а вы не хотите оценить выражения, мы можем - как говорит @DanielLyons - просто использовать V = W:

set(V, W) :-
    term_variables(V, VV),
    all_diff(VV),
    <b>V = W</b>.

Поскольку алгоритм объединения будет " peal " функторами, и, таким образом, в конечном итоге откроет все элементы в левом списке со значениями в правом списке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...