PROLOG: Проверьте, содержит ли первый список в 3 раза меньше каждого элемента, чем второй список - PullRequest
2 голосов
/ 23 ноября 2011

Мне нужно проверить, имеет ли каждый элемент во втором списке в 3 раза больше экземпляров, чем тот же элемент в первом списке.Моя функция все время возвращает false, и я не знаю, в чем я не прав.

Вот код:

fourth(_,[ ]).
fourth(A,[HF|TF]) :-
    intersection(A, HF, NewA),
    intersection(TF, HF, NewB),
    append(HF, NewB, NewT),
    append(NewA, NewA, NewAA),
    append(NewA, NewAA, NewAAA),
    length(NewAAA) == length(NewT),
    select(HF, TF, NewTF),
    fourth(A, NewTF).

Пример:

?- fourth([1,2,3], [1,1,1]).
true.

?- fourth([1,2,3], [1,1,1,1]).
false.

?- fourth([1,2,3], [1,1]).
false.

?- fourth([1,2,2,3], [1,1,2,2,1,2,2,2,2]).
true.

Ответы [ 4 ]

3 голосов
/ 23 ноября 2011

Я бы сделал себе предикат select/3: select(X,From,Left), а затем для каждого elt из первого списка я бы назвал его три раза с одним и тем же первым аргументом во втором списке, постепенно передавая его вперед, получая мнеокончательный Left3 без трех вхождений X;и я бы сделал , что для каждого эльта первого списка.Тогда, если мне удастся и я получу пустой список, это означает, что в нем будет ровно три раза каждый эльт из первого списка.

2 голосов
/ 23 ноября 2011

Ваш код кажется излишне сложным. Он также содержит ошибки, в которых вы используете HF вместо списка [HF].

Так какую логику вы хотите реализовать?:

  1. взять следующий элемент из второго списка (оставив хвост)
  2. проверить, есть ли он в первом списке, и, если он есть, удалить его (иначе ошибка)
  3. удалите его еще два раза из хвоста второго списка

и это дает:

fourth(_,[ ]).
fourth(A,[HF|TF]) :-
     once(select(HF, A, AR)), % using once/1 to avoid choicepoints
     once(select(HF, TF, TF1)),
     once(select(HF, TF1, TFR)),
     fourth(AR, TFR).
1 голос
/ 23 ноября 2011

Вот ваш код с предложениями о том, почему он не работает:

fourth(_,[]).
fourth(A,[HF|TF]) :-
    intersection(A, HF, NewA),
    intersection(TF, HF, NewB),

Это не пересечение / 3 , которое вы хотите использовать по двум причинам:

1) он не фильтрует только HF в A.

2) он не работает, если вы вызываете его с элементом, поэтому, по крайней мере, используйте [HF] вместо HF

Вместо этого используйте include / 3 : include (= (HF), A, NewA).См. Документ SWI-pl для получения дополнительной информации.

    append(HF, NewB, NewT),
    append(NewA, NewA, NewAA),
    append(NewA, NewAA, NewAAA),

Лучше использовать append / 2 , особенно для вашего списка NewAAA.

    length(NewAAA) == length(NewT),

Вы можете 'т сравнить длины как это.Во-первых, length / 1 не существует во встроенных предикатах swi-pl.Вместо этого сравните непосредственно списки или дважды используйте length / 2 , а затем сравните результаты.

    select(HF, TF, NewTF),
    fourth(A, NewTF).

Только удаление один раз HT в TF приведет к сбою вашего алгоритма.Вам необходимо удалить все вхождения HT в TF, например, вычитать / 3 ...

Если вы хотите рабочее решение, соответствующее вашей первоначальной работе, я добавлю его,так что не стесняйтесь спрашивать, но так как это было помечено как домашнее задание, я сначала дам вам эти рабочие поводыри ...

0 голосов
/ 17 декабря 2016

% Блоки в нашем "мире блоков"%% b3% b4 b7% b1 b5 b8% b2 b6 b9% =============

% Укладка блоков на(b1, b2).на (В3, В4).на (В4, В5).на (В5, В6).на (В7, В8).вкл (b8, b9).

% Порядок стеков оставлен (b2, b6).Слева (b6, b9).

% Обобщение «сверху» сверху (вверху, внизу): - вкл. (сверху, внизу).выше (выше, ниже): - включено (выше, AnyBlock), выше (AnyBlock, ниже).

% isLeft (X, Y) разрешается в значение true, если X - блок слева от любого блока Y.%isLeft / 2 просто вызывает leftOf / 2 с последующим вырезом (!), чтобы гарантировать, что% будет сгенерирован только один результат.%% Например: isleft (b1, b7) выдает true% isleft (b2, b6) выдает true% isleft (b4, b5) выдает false.% isleft (b9, b3) выдает false.

isLeft (X, Y): - leftOf (X, Y),!.% Показать реализацию leftOf ниже.Реализация будет включать%% случаев (как вышеупомянутый предикат выше), но может быть завершена с использованием только предоставленных% и левого предикатов.

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