Как объединить все не-числа в список в Прологе?

#prolog

Вопрос:

У меня есть базовый вариант

 variable_part(X) :- var(X), !.
variable_part(X) :- number(X).
variable_part(X Y) :- variable_part(X), variable_part(Y).
variable_part(X-Y) :- variable_part(X), variable_part(Y).
 

Я пытаюсь сделать так, чтобы все элементы списка имели номер атома формы*и чтобы они были отсортированы, но я не совсем уверен, с чего начать.

Комментарии:

1. Хотели бы вы также «так,например, variable_part(5-(3 x), N) должен иметь успех при N=2» ?

Ответ №1:

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

 variable_part(X,[X]) :- var(X).
variable_part(X,[]) :- number(X).
 

Для рекурсии вам нужно объединить списки переменных:

 variable_part(Op,Vars) :-
    nonvar(Op),
    Op = X   Y,
    variable_part(X,V1),
    variable_part(Y,V2),
    append(V1,V2,Vars).
 

Я также удалил вырезку из базового варианта и заменил ее явной проверкой на неверность с последующей унификацией для рекурсивных случаев. В качестве следующего шага вы можете заменить добавление предикатом, который объединяет переменные в вашем представлении умножения (в качестве альтернативы вы делаете это как шаг постобработки). Вы могли бы облегчить себе жизнь, выбрав атомы для представления переменных вашей системы уравнений (см. Также это обсуждение чистого представления по сравнению с представлением по умолчанию).

 variable_part(v(X),[(X,1)]).
variable_part(X,[]) :- number(X).
variable_part(X Y,Vars) :-
    variable_part(X,V1),
    variable_part(Y,V2),
    append(V1,V2,Vars).
variable_part(X - Y,Vars) :-
    variable_part(X,V1),
    variable_part(Y,V2),
    append(V1,V2,Vars).
 

и используйте его для такого запроса, как этот:

 ?- variable_part((23 v(x))-(v(y)-v(x)), Vs).
Vs = [(x, 1),  (y, 1),  (x, 1)] ;
false.
 

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