在 Prolog 中保留值
Retaining values in Prolog
我们可以说:
Sum is 0.
Sum is Sum + 2.
在 Prolog 中,如果我们想要保留一个值或想要继续更改该变量?
是的,我们可以这么说,但结果会是
fail.
失败,因为 0 is 0+2
与 0 is 2
相同,无法成立。
如果我们想以某种方式记录我们程序中知识提炼的进展,我们可以使用编号变量,作为一种选择:
Sum1 is 0, Sum2 is Sum1 + 2.
因此,我们可以使用两个值 - 以前的值和当前值。
另一种选择是维护已记录更改的列表,其中列表中的每个元素都是前一个元素的下一个版本。
在这方面,Prolog 非常类似于 functional programming(*) in e.g. Haskell etc., forcing us to essentially program in SSA 风格,或状态传递。
(*) 在那里搜索“如何“思考功能””。
if we want a value to be retained or want to keep making changes to
that variable?
- 一般来说,我们不会。
- 在极端情况下,我们可以。
我们通过变量名(这是对全局可访问结构的引用)接收一个现有事物,从中构建一个新事物,并将对这个新事物的引用填充到另一个变量名中:
DataOut is 2*DataIn. % assuming DataIn is numeric, multiply by 2
bar(DataIn,DataOut) :-
DataIn = f(X), % Disassemble, pick out X, assuming DataIn is a term "f(X)"
DataOut = g(X). % Assemble, wrapping X into g
baz(f(X),g(X)). % the same as bar/2 above, written compactly
“事物”从不存储,它们只是在谓词之间传递。
特别是,对于循环,您不存储任何内容。
这里是 From
和 To
之间的值的总和:
% loop(From:integer,To:integer,Sum:integer).
loop(From,From,From).
loop(From,To,Sum) :-
To > From,
ToMinus is To-1,
loop(From,ToMinus,LowerSum),
Sum is LowerSum+To.
相对于函数式语言,我们有一点优势,因为它实际上可以在“尚未设置的地方”生长。所以你也可以通过一个“东西”让它成长:
quux(Data) :-
Data = f(X,Y), % Disassemble, assuming Data is a term "f(X,Y)"
(var(Y) % If Y is still an unbound variable
-> Y = g(Z) % then set it to a fresh unbound variable wrapped in g
; true). % Otherwise do nothing
等等:
?- Data=f(X,Y),quux(Data).
Data = f(X,g(_16532)),
Y = g(_16532).
?- Data=f(1,2),quux(Data).
Data = f(1,2).
然而,一旦你习惯了这个想法,你确实可以通过各种方式存储这些东西以供“以后使用”:
阅读这些:
我们可以说:
Sum is 0.
Sum is Sum + 2.
在 Prolog 中,如果我们想要保留一个值或想要继续更改该变量?
是的,我们可以这么说,但结果会是
fail.
失败,因为 0 is 0+2
与 0 is 2
相同,无法成立。
如果我们想以某种方式记录我们程序中知识提炼的进展,我们可以使用编号变量,作为一种选择:
Sum1 is 0, Sum2 is Sum1 + 2.
因此,我们可以使用两个值 - 以前的值和当前值。
另一种选择是维护已记录更改的列表,其中列表中的每个元素都是前一个元素的下一个版本。
在这方面,Prolog 非常类似于 functional programming(*) in e.g. Haskell etc., forcing us to essentially program in SSA 风格,或状态传递。
(*) 在那里搜索“如何“思考功能””。
if we want a value to be retained or want to keep making changes to that variable?
- 一般来说,我们不会。
- 在极端情况下,我们可以。
我们通过变量名(这是对全局可访问结构的引用)接收一个现有事物,从中构建一个新事物,并将对这个新事物的引用填充到另一个变量名中:
DataOut is 2*DataIn. % assuming DataIn is numeric, multiply by 2
bar(DataIn,DataOut) :-
DataIn = f(X), % Disassemble, pick out X, assuming DataIn is a term "f(X)"
DataOut = g(X). % Assemble, wrapping X into g
baz(f(X),g(X)). % the same as bar/2 above, written compactly
“事物”从不存储,它们只是在谓词之间传递。
特别是,对于循环,您不存储任何内容。
这里是 From
和 To
之间的值的总和:
% loop(From:integer,To:integer,Sum:integer).
loop(From,From,From).
loop(From,To,Sum) :-
To > From,
ToMinus is To-1,
loop(From,ToMinus,LowerSum),
Sum is LowerSum+To.
相对于函数式语言,我们有一点优势,因为它实际上可以在“尚未设置的地方”生长。所以你也可以通过一个“东西”让它成长:
quux(Data) :-
Data = f(X,Y), % Disassemble, assuming Data is a term "f(X,Y)"
(var(Y) % If Y is still an unbound variable
-> Y = g(Z) % then set it to a fresh unbound variable wrapped in g
; true). % Otherwise do nothing
等等:
?- Data=f(X,Y),quux(Data).
Data = f(X,g(_16532)),
Y = g(_16532).
?- Data=f(1,2),quux(Data).
Data = f(1,2).
然而,一旦你习惯了这个想法,你确实可以通过各种方式存储这些东西以供“以后使用”:
阅读这些: