Вам действительно нужно преобразовывать истины в значения в Prolog?

#prolog

#пролог

Вопрос:

Я написал пузырьковую сортировку в Prolog (код ниже). Это работает, но пахнет. Я довольно новичок в prolog. Вот проблемная часть:

 % Problem: convert the true value to something
% I can actually use.
sorted_value(X,X) :- sorted(X).
sorted_value(X,[]) :- not(sorted(X)).
  

Странно, что мне нужно использовать эту функцию для преобразования истинного значения во что-то (в данном случае, []) и False в другое, чтобы использовать их. Нет ли более чистого способа?

 % Bubble Sort a list.

% is the list sorted?
sorted([]).
sorted([Head|[]]).
sorted([First|[Second|Rest]]) :-
  min(First,Second,First),
  sorted([Second|Rest]).

% swap all pairs in the list that
% needs to be swapped
bubble_sort_list([], []).
bubble_sort_list([Head|[]],[Head]).
bubble_sort_list([First|[Second|Rest]], [One|Solution]) :-
  min(First,Second, One),
  max(First,Second,Two),
  bubble_sort_list([Two|Rest],Solution).

% Problem: convert the true value to something
% I can actually use.
sorted_value(X,X) :- sorted(X).
sorted_value(X,[]) :- not(sorted(X)).

% Repeatedly call bubble_sort until
% the list is sorted
bubble_sort_helper([],List, Solution) :-
  bubble_sort_list(List, SortedList),
  sorted_value(SortedList, Value),
  bubble_sort_helper(Value,SortedList, Solution).
bubble_sort_helper(A,List,List).

% this is what you call.
buuble_sort(List,Solution) :-
  bubble_sort_helper([],List,Solution).
  

Ответ №1:

Каждый вызов предиката либо завершается успешно (возможно, несколько раз), либо завершается неудачей. Если вы мыслите декларативно и действительно описываете, что такое отсортированный список, то, по-видимому, редко возникает необходимость в явном представлении самого истинностного значения в программе. Скорее, обычно было бы достаточно поместить вызов предиката типа «по возрастанию (список)» в программу Prolog, чтобы описать случай отсортированного списка. Кажется, нет никакого преимущества в том, чтобы вместо этого вызывать предикат типа «по возрастанию (список, T)», а затем использовать T для различения падежей. Почему бы не использовать неявное значение истинности самого предиката напрямую? Если вам действительно нужно конкретизировать значение истинности, вы можете, например, сделать это так, чтобы избежать повторного вызова ascending /1 дважды:

 ascending(Ls, T) :- 
    (   ascending(Ls) -> T = true
    ;   T = false
    ).
  

Обратите внимание, как истинность по возрастанию / 1 используется для различения падежей.