【问题标题】:How to append a string to another string in a third string in SWI Prolog?如何将一个字符串附加到 SWI Prolog 中第三个字符串中的另一个字符串?
【发布时间】:2012-12-20 14:31:35
【问题描述】:

在这个程序之前,我在下面的例子中看到了一个元素 X 是否属于一个字符串 L。

本例代码如下:

member2(X, [X|_]).
member2(X,[_|T]):- member2(X,T).

我有一个表示基本情况的事实(如果 X 元素在列表的头部,则它属于列表),并且如果元素 X 不是,则使用该规则在列表的尾部递归搜索头……

这个版本对我来说非常晦涩难懂,有人建议我以这种方式查看它以了解它的工作原理:

member2(X, [X|_]).
member2(X,Y):- Y = [_|T],
               member2(X,T).

这样意思就更清楚了:

我有一个代表基本情况的事实(如果 X 元素位于列表的头部,则它属于列表)。

规则说我必须证明两件事:

1) Y = [_|T] 这是真的,因为匿名变量 _ 与任何东西都统一

2) 递归搜索尾列表中的元素X

好的,现在我在理解这个新练习时遇到了问题,我必须编写一个 SWI Prolog 程序,给定两个字符串,将第二个字符串连接到第三个字符串中的第一个字符串

解决办法是:

myappend([], L, L).
myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

我有一些问题要理解它是如何工作的

我知道事实代表基本情况:当第一个参数是一个空列表[]并且第二个参数是一个非空列表时,第一个参数和第二个参数的连接是第二个参数列表(和这等于第三个参数)

该规则表示第一个参数不是空列表的一般情况......所以我认为当这种情况发生时它会删除 L1 参数的头部(第一个列表的头部)直到这是一个空list [],所以我会有基本情况,第三个参数统一到第二个......然后做回溯......

但我很难理解该规则是如何运作的:

myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).

我正在尝试做类似上一个示例的操作,并将其翻译成更具逻辑性的形式,因为这种方式对我来说非常不清楚......但我不知道该怎么做......我该怎么做

这条规则背后的逻辑是什么?什么意思?

【问题讨论】:

    标签: prolog declarative


    【解决方案1】:
    myappend([], L, L).
    
    myappend([X|L1], L2, [X|L]) :- myappend(L1,L2,L).
    

    第二条规则的更长版本:

    myappend(L1, L2, Concat) :- 
        L1 = [HeadL1|RestL1], Concat = [HeadConcat|RestConcat], 
        HeadL1 = HeadConcat,
        myappend(RestL1,L2,RestConcat).
    

    第一个规则意味着,如果第一个列表为空,则连接的列表与第二个列表相同。

    第二条规则意味着,最终列表将由第一个列表X 的第一个元素和一个列表L 组成,该列表是第一个列表L1 和第二个列表的其余部分的串联列出L2。注意,由于[X|L1]的约束,第一个参数只有为列表且不为空时才能统一。

    您可以将谓词视为测试第一个、第二个和第三个参数是否具有第一个和第二个连接的关系是第三个参数。由于在 Prolog 中提取列表的头元素既简单又高效,所以上面的解决方案挑选出第一个元素,匹配它们([X|L1] 和[X|L])并测试其余元素是否满足串联关系。

    【讨论】:

    • mmm 现在更清楚了,但一点也没有……你能帮我像之前的例子那样把它写成扩展的形式吗? Tnx
    • Andrea 这里是一个小费。如果您使用的是 SWI-Prolog,请键入 trace。(启用跟踪)然后调用谓词 myappend/3。 (使用您自己的列表值)。走着瞧吧。事情应该会变得更清楚。希望这会有所帮助。
    【解决方案2】:

    串联([ ],L,L)。

    连接( [X | L1 ], L2, [ X | L ] ):- 串联(L1,L2,L)。

    这里我们在现有列表的末尾添加元素/列表。

    连接(现有列表,元素,[现有列表|元素])

    1 -> 如果列表为空,则连接的列表将是第二个列表。 对于第二个语句,例如: 现有列表 = [1,2]
    添加元素 3

    连接([X|L1], L2, [X|L]):- 连接(L1、L2、L)。

    连接 ([1|2], 3, [1|x]):-

    连接 ([2],3,[2|y]):- (x= [2|y];)

    连接 ([], 3, 3)。 (y = 3;)

    因此最终列表变为 [1,2,3]。

    【讨论】:

    • 嗨,欢迎来到 StackOverflow。您的答案有一些格式问题。请查看这篇文章,了解如何更好地格式化您的帖子stackoverflow.com/help/formatting :) 祝你好运
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-25
    • 1970-01-01
    • 2017-06-06
    • 2020-04-13
    • 1970-01-01
    相关资源
    最近更新 更多