Пролог: сравнение соответствующих элементов в 2 списках
У меня 2 списка [x1, x2, ...xn]
а также [y1, y2, ...yn]
формы {0, 1}^n
,
Я хочу создать новый список [a1, a2 ... an]
такой, что ai = xi AND yi
для каждого i
от 1 до n (т. е. если x1 = y1 = 1, то a1 = 1 или если x1 = 1, y1 = 0, то a1 = 0)
Как я могу реализовать предикат, используя рекурсию?
2 ответа
Используйте clpb и мета-предикат maplist/4
вместе с лямбдами Пролога вот так:
? - use_module ([библиотека (clpb), библиотека (лямбда)]). правда. ? - список карт (\ A ^ B ^ AB ^ sat (A * B =: = AB), [1,1,0,0], [1,0,0,1], Товары). Продукты = [1,0,0,0].
Отказ от ответственности: Этот ответ является просто более явной версией комментария @lurker для потомков.
Во-первых, как вы делаете AND? Один простой вариант - использовать побитовое И:
and(A, B, R) :- R is A /\ B.
Теперь то, что вы хотите, так же просто, как:
?- maplist(and, [1, 0, 0, 1], [0, 1, 0, 1], L).
L = [0, 0, 0, 1].
Что это maplist
? Поскольку код SWI-Prolog доступен и его легко просматривать, вы можете посмотреть стандартное определение библиотеки:
maplist(Goal, List1, List2, List3) :-
maplist_(List1, List2, List3, Goal).
maplist_([], [], [], _).
maplist_([Elem1|Tail1], [Elem2|Tail2], [Elem3|Tail3], Goal) :-
call(Goal, Elem1, Elem2, Elem3),
maplist_(Tail1, Tail2, Tail3, Goal).
Это более общее, чем вам, вероятно, нужно. Во-первых, вам не нужно проходить and/3
к предикату, который вы хотите написать, вы можете просто вставить его. Итак, вы замените call
с and
или просто с is
, Теперь вам также не нужно переупорядочивать аргументы, поэтому вам не нужно иметь предикат и предикат помощника.
Там так много кода, что стыдно не смотреть на него и пытаться учиться.