Новичок пролога: Как объединить с арифметическими операторами сравнения или как получить var набора к диапазону значений

Я плохо знаком с Прологом. Я должен записать целочисленный сумматор, который добавит числа между 0-9 к другим номерам 0-9 и произведет решение 0-18. Это - то, что я хочу сделать:

% pseudo code
add(in1, in2, out) :-
    in1 < 10,
    in2 < 10,
    out < 18.

Я хотел бы смочь назвать его как это:

Чтобы проверить, является ли это допустимое дополнение:

?- add(1,2,3).
true.
?- add(1,2,4).
false.

С одной отсутствующей переменной:

?- add(X,2,3).
X = 1.
?- add(1,4,X).
X = 5.

С несколькими отсутствующими переменными:

?- add(X,Y,Z).
% Some output that would make sense.  Some examples could be:
X=1, Y=1, Z=2 ;
X=2, Y=1, Z=3 ......

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

"В отличие от Arithmetic Comparison Operators объединения операторы не могут использоваться для предоставления значений переменной. Банка только быть оцененным, когда каждый термин на каждой стороне были инстанцированы".

5
задан repeat 18 May 2015 в 07:21
поделиться

3 ответа

Решение:

lessThanTen(9).
lessThanTen(8).
lessThanTen(7).
lessThanTen(6).
lessThanTen(5).
lessThanTen(4).
lessThanTen(3).
lessThanTen(2).
lessThanTen(1).
lessThanTen(0).

addSimple(Add1,Add2,Sol) :-
    lessThanTen(Add1),
    lessThanTen(Add2),
    Sol is Add1+Add2.
0
ответ дан 14 December 2019 в 08:43
поделиться

Все современные системы Prolog предоставляют ограничения конечной области, которые являются истинными отношениями, которые могут (в отличие от более низкоуровневых арифметических предикатов, таких как is/2 и >/2) использоваться во всех направлениях. В SWI-Prolog:

:- use_module(library(clpfd)).

plus(X, Y, Z) :-
        [X,Y] ins 0..9,
        X + Y #= Z.

Результаты для ваших примеров:

?- plus(1,2,3).
true.

?- plus(1,2,4).
false.

?- plus(X,2,3).
X = 1.

?- plus(1,4,X).
X = 5.

?- plus(X,Y,Z).
X in 0..9,
X+Y#=Z,
Y in 0..9,
Z in 0..18.

Поскольку предикат может использоваться во всех направлениях, больше не имеет смысла называть его "add/3", поскольку это подразумевает направление, но предикат действительно описывает, когда отношение выполняется, и поэтому является более общим.

6
ответ дан 14 December 2019 в 08:43
поделиться

Что насчет этого? :

add(X,Y,Z) :-
        Z is X + Y,
        X < 10,
        Y < 10,
        Z < 19.

Проблема: это хорошо работает для запросов вида add(1,1,X), потому что Z инстанцируется перед вызовами <, но не работает, когда вы спрашиваете add(X,1,2). Можно использовать var/1 для различения типа запроса (var/1 сообщает, является ли переменная неинстанцированной или нет), но это звучит очень мучительно.

1
ответ дан 14 December 2019 в 08:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: