2015-06-01 3 views
1

Я работаю над очень простым примером обратного списка в Prolog.Prolog возвращает true/false вместо переменной

append(A, [], [A]). 
append(A, B, [A|B]). 

reverse([], ReversedList). 
reverse([A,B], ReversedList) :- 
    reverse(B, TemporaryList), 
    append(A, TemporaryList, ReversedList). 

append работает правильно. Однако, когда я вызываю reverse, интерпретатор не отвечает переменной, как append, но вместо этого он просто пишет true или false.

Вот лог:

1 ?- consult('capitolo2'.pl). % file containing the code 
2 ?- append(a, [b,c,d], L). 
L = [a,b,c,d]. % ok, this works 
3 ?- reverse([a,b,c], L). 
false. % what? why that's not L = something? 

Платформа SWI-Prolog 7.2 на Windows,

+1

Это довольно нестандартное определение [ 'append'] (http://www.swi-prolog.org/pldoc/man?predicate=append/3), как правило,' append' определено для работы над списками, например 'append ([a, b, c], [x, y, z], L) ==> L = [a, b, c, x, y, z]', http://stackoverflow.com/questions/11539203/how-do-i-append-lists-in-prolog – npostavs

+0

Кажется, это не проблема. Если я переименую 'append' в' my_append', это то же самое – incud

+0

Вам также нужно перезапустить систему Prolog. Кроме того, существует '[A, B]', который должен, вероятно, читать '[A | B]' и многое другое ... – false

ответ

3

append/3

ли вам модульного тестирования это? Правильно ли он работал? Неверная реализация вашего append/3. Первый пункт

первый пункт:

append(A , [] , [A] ). 

просто создает список длины 1 из его 1-го аргумента (какой бы она ни). Учитывая, что, если бы вы сказали:

append([1,2,3] , [] , X) . 

Вы бы получить обратно:

X = [ [1,2,3] ] 

Список длины 1, с единственным пунктом в нем содержится быть оригинальным первым аргументом. Второе положение является так же неверно:

append(A , B , [A|B]). 

Вставляет 1-й аргумент — все, что могло бы быть, и во всей своей полноте — как глава этого списка. Учитывая, что, если бы вы сказали что-то вроде:

append([1,2,3] , [a,b,c] , X) . 

Вы бы получить обратно:

X = [ [1,2,3] , a , b , c ] . 

Список длиной 4, первый элемент которого является оригинальным первым аргументом.

Пролога является описательным языком: вы описать раствор и пусть работу двигателя вещь. append/3 утверждает, что список (3-й аргумент append/3 представляет конкатенацию 1-го аргумента и 2-го аргумента

Вот реализация append/3, упрощена для ясности:.

append([]  , RL , RL) . % The concatenation of an empty left-hand list and a right hand list is the right hand list. 
append([LH|LT] , RL , CL) :- % The concatenation of a non-empty left-hand list and a right-hand list is true IF: 
    CL = [LH|CT] ,    % - The left-hand head and the concatenation head are the same, AND 
    append(LT , RL , CT)  % - recursively, the concatenated tail represents the conconcatenation of the left-hand tail and the right-hand list. 
    .       % Easy! 

Как вы попы пунктов от . список с левой стороны, она в конечном счете разлагается завершающим особый случай Это может быть упрощено до классической реализации:

append([]  , RL , RL  ) . 
append([LH|LT] , RL , [LH|CT]) :- append(LT , RL , CT) . 

reverse/3

Аналогичным образом, ваша реализация reverse/3 неверна. Ваш первый пункт:

reverse([], ReversedList). 

довольно много говорит о том, что почти все наоборот. Поскольку ваша переменная ReversedList никогда не упоминается, ваша реализация Prolog должна хотя бы вызывать предупреждение об одноэлементных переменных здесь. Многие реализации делают ошибку.

Ваш второй пункт:

reverse([A,B], ReversedList) :- 
    reverse(B, TemporaryList), 
    append(A, TemporaryList, ReversedList). 

говорит, что реверс списка с 2-позиционным ([A,B]) получается

  • реверсивного 2-й пункт в списке (B), и
  • добавление 1-го элемента (A) к этому.

Не совсем точное описание решения. Вы можете попробовать что-то вроде

reverse([] , []) . % The empty list is already reversed, what with it being atomic and all. 
reverse([H|T] , R ) :- % a non-empty list can be reversed by decomposing it into its head and tail, and 
    reverse(T,T1) ,  % - reversing the tail, and 
    append(T1,H,R) .  % - appending the head to the now-reversed tail. 
+0

Спасибо за ваш ответ Но это была просто синтаксическая проблема.Я хотел написать reverse ([A | B], ReversedList), установленный в обратном порядке ([A, B], ReversedList) .Это по-прежнему не работает, но я знал, что алгоритм wasn ' t ok. – incud

2

Возможно есть и другие проблемы, но

  1. reverse([], ReversedList). 
    

    почти наверняка не что вы хотите здесь. Реверс пустого списка является пустым списком, переводит

    reverse([], []). 
    
  2. Кроме того,

    reverse([A,B], ReversedList) 
    

    также, вероятно, не то, что вы хотите. Это не список с головой A и хвостом B, а скорее 2-элементный список.

+0

Результат тот же :( – incud

+0

Существует, по крайней мере, еще одна проблема. См. Обновление. –

+0

Это была проблема (nr2). Теперь она не возвращает мне результат corrent, но это проблема в моем алгоритме – incud

Смежные вопросы