2013-04-22 55 views
-1

编写需要的元素本身名单和 打印在每行的内部列表中的元素列表的规则列表的列表:有关程序的声明意义有些疑惑,打印在序言

例:

? - printList [[1,a],[2,b]])。

2 B

溶液了下列之一:到达基础案例

/* BASE CASE: The list is empty, so there is nothing to print */ 
printList([]). 

printList([P|R]):- printList(P), 
        !, 
        nl, 
        printList(R). 

printList([X|R]):- write(X), 
        !, 
        printList(R). 

我有的printList规则当列表是空的,在这种情况下,没有什么可打印的。

如果我的基本情况我不是(在列表不为空),它调用第二条规则的printList([P | R]),现在我有我的第一个疑问:

元素P是一个列表,因为Prolog自动处理一个内部列表作为一个元素?

所以,如果我有类似:

[[1,],[2,B],[3,C],[4,D]]我有Prolog的自动匹配在这种方式:

P = [1,](第一列表作为头元件)

R = [[2,b],[3,C],[4,d] ](其他3个列表是尾部列表的元素)

然后程序在头元素(第一个列表)上调用谓词谓词,并且此版本的规则写入当前列表中的所有元素。

这是正确的解释吗?

现在我对这个项目的跟踪一些疑问,例如,如果我执行该语句我获得以下跟踪:

[trace] ?- printList([[1,a], [2,b]]). 
    Call: (6) printList([[1, a], [2, b]]) ? creep 
    Call: (7) printList([1, a]) ? creep 
    Call: (8) printList(1) ? creep 
    Fail: (8) printList(1) ? creep 
    Redo: (7) printList([1, a]) ? creep 
    Call: (8) write(1) ? creep 
1 
    Exit: (8) write(1) ? creep 
    Call: (8) printList([a]) ? creep 
    Call: (9) printList(a) ? creep 
    Fail: (9) printList(a) ? creep 
    Redo: (8) printList([a]) ? creep 
    Call: (9) write(a) ? creep 
a 
    Exit: (9) write(a) ? creep 
    Call: (9) printList([]) ? creep 
    Exit: (9) printList([]) ? creep 
    Exit: (8) printList([a]) ? creep 
    Exit: (7) printList([1, a]) ? creep 
    Call: (7) nl ? creep 

    Exit: (7) nl ? creep 
    Call: (7) printList([[2, b]]) ? creep 
    Call: (8) printList([2, b]) ? creep 
    Call: (9) printList(2) ? creep 
    Fail: (9) printList(2) ? creep 
    Redo: (8) printList([2, b]) ? creep 
    Call: (9) write(2) ? creep 
2 
    Exit: (9) write(2) ? creep 
    Call: (9) printList([b]) ? creep 
    Call: (10) printList(b) ? creep 
    Fail: (10) printList(b) ? creep 
    Redo: (9) printList([b]) ? creep 
    Call: (10) write(b) ? creep 
b 
    Exit: (10) write(b) ? creep 
    Call: (10) printList([]) ? creep 
    Exit: (10) printList([]) ? creep 
    Exit: (9) printList([b]) ? creep 
    Exit: (8) printList([2, b]) ? creep 
    Call: (8) nl ? creep 

    Exit: (8) nl ? creep 
    Call: (8) printList([]) ? creep 
    Exit: (8) printList([]) ? creep 
    Exit: (7) printList([[2, b]]) ? creep 
    Exit: (6) printList([[1, a], [2, b]]) ? creep 
true. 

这对我来说是很清楚(我觉得我以前的推理是正确的),但我不理解为何当它到达它调用就可以了的printList关系(这是一个简单的元素,而不是一个列表)内部列表中的元素,例如这里:

Call: (8) printList(1) ? creep 
    Fail: (8) printList(1) ? creep 

日C计划审议了原始列表的第一个列表,然后将它必须打印的第一个元素,为什么叫这个简单的元素

的printList关系是不是因为这个简单的元素可能反过来是内部列表吗?

是这样的:

[[[1.1,A1,A2],[1.2,B1,B2]],[2,b]的](其中我有一个包含2所列出的列表和第一个元素是包含2所列出所以程序检查列表如果一个元素是一个元素或内部列表

回答

2

我觉得你过于思前想看看代码:?

printList([P|R]):- printList(P), 

就在那里你可以看到printList/1正与名单的头。事实上,printList/1的所有规则都与列表和列表相匹配,这是人类可以立即看到的事实。但序言没有“通知”这一事实,所以如果你是打电话,说,

printList([1]) 

第一个匹配的规则是上面的一个,所以它会立即试图统一printList(1)。这当然会失败,因为1不是一个列表,因此不符合printList/1的任何规则。序言然后回溯并尝试下一个规则,这是启动这样的一个:

printList([X|R]):- write(X), 

这显然将统一[1],其中X = 1,R = [],因此它明显地将写第一个元素,一个,然后照常进行。这里并没有涉及“内部列表”的魔术,据我所知,它根本不是Prolog中的一个概念(如果在编译器中处理这样的事情,它对Prolog的用户来说是隐藏的)。

序言不是通灵;它必须尝试规则来判断它们是否失败,即使这种尝试实质上是Horn子句头部的模式匹配失败。

我无法区分你的第一个问题和你的第二个问题,所以我希望这两个答案都可以。 :)

+0

Tnx这么多;-) – AndreaNobili 2013-04-22 14:11:09