В вашей программе есть небольшая ошибка. Строка Total = Head + Sum
означает, что Total
является структурой +
с двумя аргументами. Вероятно, вы имеете в виду is
вместо =
, что означает арифметическую оценку. Но лучше всего использовать #=
.
На ваш вопрос вы задаете , что программа сделает. Это довольно разумный вопрос в командно-ориентированных («императивных») языках, поскольку единственное значение, которое вы можете вывести из программы, - это пошаговое действие. Но здесь, в Prolog, все немного по-другому. Вы все же можете попытаться применить это пошаговое мышление, но рано или поздно вы поймете, что здесь все может стать чрезвычайно сложным, просто потому, что у Пролога нет одного потока управления, но два одновременно вызываются (AND- и OR- контроль). И даже «структуры данных» различны ...
Но есть способ прочитать программу Prolog, которая не имеет аналогов в императивных языках: вы можете понимать программу как отношение между аргументами. Таким образом, вы можете сосредоточиться на том, как выглядит отношение по процедурным аспектам. В конце концов, если описанное отношение неверно, нет смысла спрашивать, как это делает программа.
Итак, позвольте мне перефразировать свою программу:
:- use_module(library(clpfd)).
list_sum([], 0).
list_sum([E|Es], S) :-
S #= E+T,
list_sum(Es, T).
это первый проверит первое условие list_sum ([], 0). в то время как условие не выполняется, оно будет делить список на 2 части H и T тогда?
Ваш вопрос подразумевает, что существует единственный поток управления («хотя это такая типичная конструкция, которая подразумевает это»). Но это может также работать по-другому. Рассмотрим запрос:
?- list_sum(Xs,0).
Xs = [] ;
Xs = [0] ;
Xs = [_G1710, _G1713],
_G1710+_G1713#=0 ...
Здесь мы задаем Что списки существует, сумма которых равна 0. Теперь ваше «время» больше не имеет смысла.
Ответы, которые мы получаем: пустой список; список с 0
; список из двух элементов, где сумма элементов равна 0; и т.д ...
Лучший способ понять такие программы, чтобы читать их как отношения, как так:
list_sum([], 0
: Пустой список имеет сумму 0.
правило теперь гласит лучший в направлении стрелки :-
то есть справа налево:
list_sum(Es, T).
: * Предоставлено Es
список с суммой T
и ...
S #= E+T
: ... S
это E
плюс T
...
:-
... то мы можем заключить, что ...
list_sum([E|Es], S)
: S
- сумма, содержащая список [E|Es]
.
Таким образом, это можно понять, не обращая слишком много внимания на процедурные детали. Это больше похоже на понимание термина, см. failure-slice.
Полностью оценить его. Большое спасибо . Будьте здоровы . Мне было слишком трудно понять это в первом. Но вы все упростили для меня – user3018890
Хорошее объяснение, но «возвращение с 102» и т. Д. Немного вводит в заблуждение, особенно для тех, кто привык думать сообразительно. Предложения Prolog не возвращают значения; они вообще не «возвращаются». Было бы точнее сказать что-то вроде «преуспевает с« Х », связанным с 102» и т. Д. –
@TedHopp Я тоже об этом подумал - возврат немного вводит в заблуждение. Я добавил «с», пытаясь предположить, что значение не возвращается в процедурный смысл. Мне нравится ваша формулировка лучше, чем моя, хотя, спасибо за отличный комментарий! – dasblinkenlight