以下序言代码有什么作用? [英] what does the follow prolog codes do?

查看:37
本文介绍了以下序言代码有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解下面的代码.
如果我有以下输入,有人可以逐步解释发生了什么:

I am having trouble understanding the codes below.
Can someone explain step by step what is happening if I have the follow input:

append([1,2,3], Lst).

实际上,我不明白 1 和 2 是如何附加到列表 Lst 的.

Actually, I don;t get how 1 and 2 is appended the list Lst as a result.

append([_], []).    
append([H|T], [H|N]) :- append(T,N).

推荐答案

听起来您是 Prolog 的新手.如果是这样,欢迎!我们来分析一下.

It sounds like you're new to Prolog. If so, welcome! Let's analyze this.

这个不幸命名的函数有两个子句.Prolog 会查看这些子句,以确定哪一个适用.当它找到一个匹配时,它会尝试执行它.如果在某处执行失败,它将备份并尝试下一个选项.这些选择点的确切位置因程序而异;在这个程序中,唯一的一个将在子句级别,决定使用哪个规则.

This unfortunately-named function has two clauses. Prolog looks at the clauses in order to see which one applies. When it finds one that matches, it tries to perform it. If there's a failure somewhere in performing it, it will back up and try the next option. Where precisely these choice points are varies depending on the program; in this program, the only one will be at the clause level, deciding which rule to use.

查看第一条规则的一种方式是它说具有一个元素的列表,无论该元素是什么,都与空列表相关."看看 append([_], []),如果我们有 X = [foo]Y = [],它会成立,因为 [foo] 是一个单项列表,而 [] 是空列表.这个规则是很好的 Prolog 风格,因为无论实例化如何它都可以工作:我们可以提供左边或右边或都不提供,这无关紧要.

One way of looking at the first rule is that it is saying "A list with one element, regardless of what that element is, is related to the empty list." Looking at append([_], []), if we had X = [foo] and Y = [], it would hold, because [foo] is a one-item list and [] is the empty list. This rule is good Prolog style, because it will work regardless of instantiation: we could supply the left or the right or neither, it doesn't matter.

第二个子句也很简单.它表示,如果左参数和右参数都以相同的项目开头,并且列表的其余部分也通过相同的谓词相关,则它们是相关的.换句话说,如果我有两个列表 XY 使得 append(X, Y) 为真,那么 append([H|X], [H|Y]) 也是如此.H 是什么并不重要,X 和 Y 是什么也不重要,除非 append/2 暗示.

The second clause is also quite simple. It says that the left argument and the right argument are related if they both start with the same item, and if the rest of the lists are also related by this same predicate. In other words, if I have two lists X and Y such that append(X, Y) is true, then append([H|X], [H|Y]) is also true. It doesn't matter what H is and it doesn't matter what X and Y are, except insofar as would be implied by append/2.

从逻辑上思考,如果我知道任何单项列表与空列表相关,并且任何列表与以相同项目开头的列表相关,否则相同,唯一可以如此相关的是每个项目都相同的列表,除了左边的列表最后还有一个不在右边的项目.所以 [1,2,3,4] 与 [1,2,3] 相关,但 [1,2,3,foo] 和 [1,2,3] 也是如此.

Thinking logically, if I know that any one-item list is related to the empty list, and any list is related to a list that starts with the same item and otherwise is the same, the only kinds of lists that can be so related are lists where every item is the same, except the left list has one more item in it at the end which is not present on the right. So [1,2,3,4] is related to [1,2,3], but so is [1,2,3,foo] and [1,2,3].

在程序上,让我们看看用这组参数处理这个谓词时会发生什么:

Procedurally, let's look at what happens as this predicate is processed with this set of arguments:

append([1,2,3], X).

第一个规则在 [1,2,3] 上不匹配.所以我们必须看第二条规则:

The first rule won't match on [1,2,3]. So we must look at the second rule:

append([1|[2,3]], [1|X]) :- append([2,3], X).

我们可以重复:

append([2|[3]], [2|Y]) :- append([3], Y).

现在第一条规则确实匹配:

append([3], []).

所以把它们放在一起:

append([1,2,3], [1|X]) implies
  append([2,3], X=[2|Y]) implies
    append([3], Y=[])
  so Y = []
so X = [2]
so the right side is [1,2].

Prolog 跟踪将向您显示基本相同的信息:

A Prolog trace will show you basically the same information:

?- trace, append([1,2,3], X).
   Call: (7) append([1, 2, 3], _G1633) ? creep
   Call: (8) append([2, 3], _G1752) ? creep
   Call: (9) append([3], _G1755) ? creep
   Exit: (9) append([3], []) ? creep
   Exit: (8) append([2, 3], [2]) ? creep
   Exit: (7) append([1, 2, 3], [1, 2]) ? creep

这个 Prolog 代码令人困惑的地方在于,它看起来并没有告诉 Prolog 如何做任何事情.这是真的,您还没有,但是通过指定逻辑上正确的内容,Prolog 能够自己弄清楚.这是非常聪明的代码.如果这是 Haskell,我们将讨论内置函数 init,它返回除最后一项之外的所有列表.

What makes this Prolog code confusing is that it doesn't look like you've told Prolog how to do anything. And it's true, you haven't, but by specifying what is true logically, Prolog is able to figure it out by itself. This is pretty clever code. If this were Haskell, we'd be talking about the built-in function init, which returns all of the list but the last item.

希望这会有所帮助!

这篇关于以下序言代码有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆