Prolog return 值比较
Prolog return value comparation
我正在学习逻辑编程的基础知识。
我解决了一些练习,现在我在创建一个带有两个参数的函数时遇到了麻烦,一个非空列表的列表,其元素连接在一起形成第二个参数。
当我创建一个连接列表列表元素的函数时:
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3),!.
现在,我需要知道的是如何获取该函数的 return 值并将其与列表(函数的第二个参数)进行比较。
Prolog 没有过程编程语言意义上的函数或 return 值。它有 断言关系的断言 。它有术语,其中包括 variables,其中有一些限制:
- 所有变量都是局部变量,并且
- 一个变量,一旦赋值,就不再是变量。这就是为什么它被称为统一。
所以....
如果您想要一个将接受两个列表并产生它们的串联的谓词,您需要将第三个变量传递给它。您可以这样调用它:
concat([a,b],[c,d],X).
断言 X
是 [a,b]
和 [c,d]
的串联。 Prolog 的推理引擎随后将评估断言的真假。
大多数递归问题都有一些特殊情况和更一般的情况。这种 concat/3
谓词的实现可能看起来像这样(注释以解释它在做什么)。
首先,我们有一个特殊(且终止)的情况:如果左侧列表为空,则连接只是右侧列表。
concat( [] , Bs , Bs ).
接下来,我们有一个一般情况:如果左侧列表非空,我们需要将它添加到我们正在构建的连接中(然后向下递归。)
concat( [A|As] , Bs , [A|Cs] ) :-
concat(As,Bs,Cs).
只有两个。您还会注意到它是双向的:它也很乐意将列表分开。像这样调用它:
concat( Prefix , Suffix, [a,b,c,d] ).
将在回溯时生成所有可能的方式 [a,b,c,d]
可以拆分为前缀和后缀:
Prefix Suffix
--------- ---------
[] [a,b,c,d]
[a] [b,c,d]
[a,b] [c,d]
[a,b,c] [d]
[a,b,c,d] []
这是一种允许子列表中的单个元素的方法,但不允许空子列表:
concat([[L]], [L]).
concat([[H],L|T], [H|R]) :- concat([L|T], R).
concat([[H1,H2|T]|LT], [H1|RT]) :- concat([[H2|T]|LT], RT).
这里避免空列表的方法是在递归子句中调出两个头元素,在基本情况中调出一个单独的元素列表。这可以防止空子列表成功,正如原始 post.
的评论中所要求的那样
如果你有一个已经实例化的变量Y
,你想知道它是否是连接列表列表LL
的结果,你只需查询:
concat(LL, Y).
如果 Y
是列表 LL
的串联,这将是 true
,如果不是,则为 false
。您不必 "return and compare"(例如,在 C 中,您可能会说 concat(LL) == Y
或 concat(LL, X); if (X == Y)...
)。这是因为 concat
是定义在两个参数之间的 关系 并且它确定是否可以按照规定的规则(谓词的子句)进行查询 true
).
如果你已经得到一个结果,想确定它是否可以统一到另一个变量,Z
,那么你可以说:
concat(X, Y), Y = Z.
注意,在Prolog中,concat(X, Y) == Z
判断谓词的结果是否等于Z
是不正确的,因为它不是returns一个值的函数。
您只需要基本案例
concat([],[]).
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3).
它也适用于空(子)列表。
我已经删除了无用的剪辑。
我正在学习逻辑编程的基础知识。 我解决了一些练习,现在我在创建一个带有两个参数的函数时遇到了麻烦,一个非空列表的列表,其元素连接在一起形成第二个参数。
当我创建一个连接列表列表元素的函数时:
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3),!.
现在,我需要知道的是如何获取该函数的 return 值并将其与列表(函数的第二个参数)进行比较。
Prolog 没有过程编程语言意义上的函数或 return 值。它有 断言关系的断言 。它有术语,其中包括 variables,其中有一些限制:
- 所有变量都是局部变量,并且
- 一个变量,一旦赋值,就不再是变量。这就是为什么它被称为统一。
所以....
如果您想要一个将接受两个列表并产生它们的串联的谓词,您需要将第三个变量传递给它。您可以这样调用它:
concat([a,b],[c,d],X).
断言 X
是 [a,b]
和 [c,d]
的串联。 Prolog 的推理引擎随后将评估断言的真假。
大多数递归问题都有一些特殊情况和更一般的情况。这种 concat/3
谓词的实现可能看起来像这样(注释以解释它在做什么)。
首先,我们有一个特殊(且终止)的情况:如果左侧列表为空,则连接只是右侧列表。
concat( [] , Bs , Bs ).
接下来,我们有一个一般情况:如果左侧列表非空,我们需要将它添加到我们正在构建的连接中(然后向下递归。)
concat( [A|As] , Bs , [A|Cs] ) :- concat(As,Bs,Cs).
只有两个。您还会注意到它是双向的:它也很乐意将列表分开。像这样调用它:
concat( Prefix , Suffix, [a,b,c,d] ).
将在回溯时生成所有可能的方式 [a,b,c,d]
可以拆分为前缀和后缀:
Prefix Suffix
--------- ---------
[] [a,b,c,d]
[a] [b,c,d]
[a,b] [c,d]
[a,b,c] [d]
[a,b,c,d] []
这是一种允许子列表中的单个元素的方法,但不允许空子列表:
concat([[L]], [L]).
concat([[H],L|T], [H|R]) :- concat([L|T], R).
concat([[H1,H2|T]|LT], [H1|RT]) :- concat([[H2|T]|LT], RT).
这里避免空列表的方法是在递归子句中调出两个头元素,在基本情况中调出一个单独的元素列表。这可以防止空子列表成功,正如原始 post.
的评论中所要求的那样如果你有一个已经实例化的变量Y
,你想知道它是否是连接列表列表LL
的结果,你只需查询:
concat(LL, Y).
如果 Y
是列表 LL
的串联,这将是 true
,如果不是,则为 false
。您不必 "return and compare"(例如,在 C 中,您可能会说 concat(LL) == Y
或 concat(LL, X); if (X == Y)...
)。这是因为 concat
是定义在两个参数之间的 关系 并且它确定是否可以按照规定的规则(谓词的子句)进行查询 true
).
如果你已经得到一个结果,想确定它是否可以统一到另一个变量,Z
,那么你可以说:
concat(X, Y), Y = Z.
注意,在Prolog中,concat(X, Y) == Z
判断谓词的结果是否等于Z
是不正确的,因为它不是returns一个值的函数。
您只需要基本案例
concat([],[]).
concat([[]|L],L3):- concat(L,L3).
concat([[Head|L1]|L2],[Head|L3]):- concat([L1|L2],L3).
它也适用于空(子)列表。 我已经删除了无用的剪辑。