Если вы напишите свое выражение следующим образом:
puzzleSimple(M,M+2).
Пролог вернет true для такого утверждения:
puzzleSimple(3,3+2). or puzzleSimple(M,M+2).
Но оно вернется false для puzzleSimple(3,5).
Здесь вы видите, что пролог не будет выполнять M+2
как арифметическую операцию, а будет использовать ее при сопоставлении с образцом.Для арифметических операций вам нужно использовать ключевое слово is
.Например:
puzzleSimple(M,V):-
V is M + 2.
Этот код вернет true для puzzleSimple(3,5).
Итак, когда вы пытаетесь напрямую использовать puzzle(M,H,M+H,M*2 + H*4).
и вызывать puzzle(M, H,8,20).
Возвращается false, потому что шаблонне соответствует.
Вы также можете изменить код следующим образом:
puzzle(M,H,X,Y):-
X is M+H,
Y is M*2 + H*4.
Теперь это будет правильно в смысле сопоставления с образцом и арифметических операций.Однако при повторном вызове puzzle(M, H,8,20).
вы увидите ошибку Arguments are not sufficiently instantiated
.Зачем?Потому что вы пытались сделать арифметическую операцию с переменной, которая не была создана.Именно поэтому в рабочем решении используется предикат between/3
.Between присваивает значение переменной и разрешает использовать возврат для поиска нескольких решений.
Примечание : Использование команды gtrace
в swipl может помочь вам в отладке кода!