Пролог, пытающийся добавить 2 списка, но продолжал становиться ложным - PullRequest
0 голосов
/ 12 октября 2018
lists([a,b,c]).

first(F):-lists([F,_,_]).  
second(S):-lists([_,S,_]).  
last(L):-lists([_,_,L]).  

sf(X):-append(second(X),first(X),X).

?-sf(X) //returns false

Я в основном пытаюсь получить возврат X = [c, a], но продолжаю получать false.

Ответы [ 2 ]

0 голосов
/ 12 октября 2018

Здесь есть несколько проблем.Прежде всего, вызов типа:

sf(X) :- append(<b>second(X)</b>, <b>first(X)</b>, X).

не имеет никакого смысла вообще: здесь second/1 и first/1 рассматриваются как функторы .Они не имеют ничего общего с предикатами second/1 и first/1 .append/3 получает три термина: second(X), first(X) и X.Однако он ожидает списки, что означает, что он ожидает пустую константу списка [] или функтор "cons" (например, [H|T], мы могли бы видеть это как функтор []/2).

Таким образом, мымы не хотим создавать функтор, мы хотим объединить список с переменной, а затем добавить их.Таким образом, мы можем переписать это следующим образом:

sf(X) :- <b>second(X)</b>, <b>first(X)</b>, append(X, X, X).

Но теперь это все еще неверно, здесь мы объединяем первый и второй список с помощью X, и добавляем его к X, append(X, X, X) canуспешен только в одном случае: если X - пустой список, так как добавление двух пустых списков приводит к пустому списку.

sf(X) :- second(<b>S</b>), first(<b>F</b>), append(<b>S</b>, <b>F</b>, X).

Но это все равно не удастся.Причина в том, что ваши предикаты first/1 и second/1 делают не возвращаемых списков, эти возвращаемые элементы.Действительно:

?- first(X).
X = a.

Вы не можете append/3 две константы b и a вместе, вы можете добавить списки с a и b вместе, так:

sf(X) :- second(S), first(F), append(<b>[S]</b>, <b>[F]</b>, X).

Предикат first/1 и second/1 также слишком специфичен : если lists/1 содержит список с четырьмя элементами, то эти предикаты завершатся ошибкой, поэтому я предлагаю вамрефакторинг эти.

0 голосов
/ 12 октября 2018

Пролог не является функциональным языком.Когда вы пишете append(second(X),first(X),X), первый и второй аргументы не заменяются соответственно lists([_,S,_]) и lists([F,_,_]).Если вы попытаетесь вместо этого:

sf(List) :-
    second(Second),
    first(First),
    append(Second, First, List).

, вы получите ошибку:

| ?- sf(List).

no

Чтобы понять почему, давайте отследим вызов в отладчике:

| ?- trace.
The debugger will first creep -- showing everything (trace)

yes
{trace}
| ?- sf(List).
      1    1  Call: sf(_279) ? 
      2    2  Call: second(_346) ? 
      3    3  Call: lists([_332,_334,_336]) ? 
      3    3  Exit: lists([a,b,c]) ? 
      2    2  Exit: second(b) ? 
      4    2  Call: first(_400) ? 
      5    3  Call: lists([_386,_388,_390]) ? 
      5    3  Exit: lists([a,b,c]) ? 
      4    2  Exit: first(a) ? 
      6    2  Call: append(b,a,_279) ? 
      6    2  Fail: append(b,a,_279) ? 
      1    1  Fail: sf(_279) ? 

(1 ms) no
{trace}

Стандартный де-факто предикат append/3, обычно доступный в виде предиката библиотеки или встроенного предиката, принимает списки в качестве аргументов, но здесь мы называем его атомами a и b.Вы можете продолжить отсюда?

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