If statement 带递归的Prolog if/else语句

If statement 带递归的Prolog if/else语句,if-statement,recursion,prolog,If Statement,Recursion,Prolog,我是prolog的新手,我正在试图弄清楚如何使用if/else语句和递归。为了说明这一点,我编写了一个简单的prolog程序。该程序是无用的(因为它的功能是无用的),但它帮助我说明我的问题。程序获取一个列表,检查列表的开头,看它是否是最后一个元素;如果不是,它会将head添加到临时列表变量,并使用列表的尾部递归运行程序。它应该在最后输出列表。该方案: gothrough([H|T], B, C):- append(B,H,B), ( (T == []) -

我是prolog的新手,我正在试图弄清楚如何使用if/else语句和递归。为了说明这一点,我编写了一个简单的prolog程序。该程序是无用的(因为它的功能是无用的),但它帮助我说明我的问题。程序获取一个列表,检查列表的开头,看它是否是最后一个元素;如果不是,它会将head添加到临时列表变量,并使用列表的尾部递归运行程序。它应该在最后输出列表。该方案:

 gothrough([H|T], B, C):-
      append(B,H,B),
      (  (T == [])
      -> C=B
      ;  gothrough(T, B, C)
      ).
呼叫:
gothrough([sample,phrase,here],[C])。

预期输出:
C=[示例,短语,此处]

当前输出:
no

我做错了什么有什么帮助吗


谢谢

第一个问题是
附加(B,H,B)
,这对于大多数输入来说是没有意义的


第二个问题是if-then-else的结果和替代方案,即
->
之后和
之后的部分必须都是Prolog目标(语句)<代码>C
不是目标。您的意思可能是
C=B
,但很难说,因为我发现很难理解您的程序在做什么。

第一个问题是
附加(B,H,B)
,这对于大多数输入来说都没有意义


第二个问题是if-then-else的结果和替代方案,即
->
之后和
之后的部分必须都是Prolog目标(语句)<代码>C
不是目标。你的意思可能是
C=B
,虽然很难说,因为我发现很难理解你的程序在做什么。

你得到的是否定,因为append(B,H,B)失败,除非H是[];记住,这些是从句,不是赋值。因为你从不把任何东西绑定到C,如果你的陈述被证明了,它就永远不会有价值

这将完成您的任务:

gothrough([],L,L).
gothrough([H|T], B, C) :- gothrough(T,B,Cx), append([H],Cx,C).

您得到的是no,因为append(B,H,B)失败,除非H是[];记住,这些是从句,不是赋值。因为你从不把任何东西绑定到C,如果你的陈述被证明了,它就永远不会有价值

这将完成您的任务:

gothrough([],L,L).
gothrough([H|T], B, C) :- gothrough(T,B,Cx), append([H],Cx,C).

从您的评论中,我了解到您误解了
append
(以及Prolog)的工作原理

这根本不是真的:“如果B=[昨天]和H=[今天],那么附加(B,H,B)=[昨天,今天]”

append(B,H,B)
的意思是“将H追加到B会再次产生B”。这仅在H为空列表时才可能

要理解的关键是
append(B,H,B)
中的两个B都是相同的,它们必须具有相同的值。这就像代数中的变量——方程中的所有X都表示相同的值


您应该为输出变量使用不同的名称,例如
append(B,H,Bnew)
,这样会更有意义。

从您的评论中,我理解您误解了
append
(以及一般的Prolog)的工作原理

这根本不是真的:“如果B=[昨天]和H=[今天],那么附加(B,H,B)=[昨天,今天]”

append(B,H,B)
的意思是“将H追加到B会再次产生B”。这仅在H为空列表时才可能

要理解的关键是
append(B,H,B)
中的两个B都是相同的,它们必须具有相同的值。这就像代数中的变量——方程中的所有X都表示相同的值


您应该为输出变量使用不同的名称,如
append(B,H,Bnew)
,这样会更有意义。

这可以更简单地完成:

gothrough([], []).
gothrough([H|T], [H|X]) :-
    gothrough(T, X).
第一条规则与空列表条件相匹配,然后强制递归结束/构建列表

第二个规则匹配除空列表以外的所有内容,在这种情况下,头H被附加到X上,其中X是通过递归尾得到的列表的结果。您不需要使用追加谓词-列表追加内置于prolog中

?- gothrough([simple, phrase, here], X).
X = [simple, phrase, here].

此解决方案还减少了一个变量。

这可以更简单地完成:

gothrough([], []).
gothrough([H|T], [H|X]) :-
    gothrough(T, X).
第一条规则与空列表条件相匹配,然后强制递归结束/构建列表

第二个规则匹配除空列表以外的所有内容,在这种情况下,头H被附加到X上,其中X是通过递归尾得到的列表的结果。您不需要使用追加谓词-列表追加内置于prolog中

?- gothrough([simple, phrase, here], X).
X = [simple, phrase, here].

此解决方案还使用了一个更少的变量。

所有
append
的参数都应该是列表,
append(B,H,B)
只有在H是空列表时才能成功。看看这段代码,很难理解为什么你认为C最终等于第一个参数,或者B到底要做什么,所以我认为你有比递归更深的问题。你完全正确……我简化了程序,忘了将C设置为B。但是你能详细说明H是空列表吗?我认为
append
将B和H的内容追加到B中。例如,如果B=[昨天]和H=[今天],那么
append(B,H,B)
=[昨天,今天]?所有
append
的参数都应该是列表,
append(B,H,B)
只有当H是空列表时才能成功。看看这段代码,很难理解为什么你认为C最终等于第一个参数,或者B到底要做什么,所以我认为你有比递归更深的问题。你完全正确……我简化了程序,忘了将C设置为B。但是你能详细说明H是空列表吗?我以为
append
会将B和H的内容追加到B中。例如,如果B=[昨天]和H=[今天],那么
append(B,H,B)
=[昨天,今天]?谢谢你的评论,是的,你完全正确。我简化了我的原始程序,但我忘了将C设置为B。所以我在我的原始帖子中编辑了它。但是我很困惑