Пролог - Изменить элементы списка - PullRequest
0 голосов
/ 05 февраля 2019

Полное новичок, выполняющий упражнения из книги, я хочу взять список X и изменить его элементы так, чтобы для некоторых [H|X] новый список Y имел бы элемент HEAD, равный (H-1,H+1).

Что-то вроде:

X=[1,20,300] --> Y=[(0,2),(19,21),(299,301)]

То, что я до сих пор добавил, - это первый элемент, но затем он возвращает странное "_number".Что у меня так далеко:

switch([], []).
switch([H|X], Y) :-
   H1 is H-1,
   H2 is H+1,
   append([(H1,H2)], [], Y).

1 Ответ

0 голосов
/ 05 февраля 2019

Здесь есть две проблемы:

  1. append ing [(H1, H2)] и [] дает нам результат, который мы можем знать заранее: Y также будет [(H1, H2)];
  2. в этом случае вы ничего не делаете с хвостом X, поэтому вы обрабатываете только первый элемент, а затем выбрасываете этот элемент.

Таким образом, ваш предикатпросто обработайте первый элемент и создайте список с этим кортежем, например:

?- switch([1,2,3], Y).
Y = [(0, 2)].

На самом деле нам здесь вообще не нужен append/3: у нас есть два параметра, и если первый не-пусто, то последнее тоже непусто и наоборот.Таким образом, наше рекурсивное предложение имеет форму:

switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
    %% ...

Таким образом, нам необходимо указать соотношение между H и H1 и H2T и TT (остальные элементы «списка кортежей»).Что касается H, это уже реализовано H1 is H-1 и H2 is H + 1 . As for T and TT , we just need to continue processing, so we make a recursive call with T and TT`:

switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
    H1 is H-1,
    H2 is H+1,
    switch(T, TT).

Использование clpfd

Здесь мы можем запрашивать только в одном направлении: если мы объединяем список из двух кортежей со вторым аргументом, то Prolog не может получить элементы впервый список.Однако мы можем определить ограничения между этими элементами, и в результате мы можем запросить в нескольких направлениях:

:- use_module(<b>library(clpfd)</b>).

switch([], []).
switch([H|T], [(H1, H2)|TT]) :-
    H1 <b>#=</b> H-1,
    H2 <b>#=</b> H+1,
    switch(T, TT).

Теперь мы можем запросить, например, с помощью:

?- switch(L, [(1, A), (3, 5), (C, 7)]).
L = [2, 4, 6],
A = 3,
C = 5.

Работа с maplist/3

Задача, которую мы решаем, является типичной «задачей картирования».Таким образом, мы можем " удалить наш шаблон " и использовать maplist/3:

:- use_module(library(clpfd)).

switch_tuple(H, (H1, H2)) :-
    H1 #= H-1,
    H2 #= H+1.

switch(L1, L2) :-
    <b>maplist</b>(switch_tuple, L1, L2).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...