Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/security/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Prolog中使用差异列表追加元素时出现问题_Prolog_Difference Lists - Fatal编程技术网

在Prolog中使用差异列表追加元素时出现问题

在Prolog中使用差异列表追加元素时出现问题,prolog,difference-lists,Prolog,Difference Lists,我在中找到了此Prolog代码,它使用差异列表实现了一个队列: %%空队列(-queue) %排空队 空_队列(队列(0,Q,Q))。 %%队列头(?队列,队列头,队列0) %已移除标头的队列为队列0 队列头(队列(s(X),[H | Q],Q0),H,队列(X,Q,Q0))。 %%队列最后(+Queue0,+last,-queue) %Queue0是队列,最后一个在后面 最后一个队列(队列(X,Q,[L | Q0]),L,队列(s(X),Q,Q0))。 做这样的事情,它的工作如预期: ...

我在中找到了此Prolog代码,它使用差异列表实现了一个队列:

%%空队列(-queue)
%排空队
空_队列(队列(0,Q,Q))。
%%队列头(?队列,队列头,队列0)
%已移除标头的队列为队列0
队列头(队列(s(X),[H | Q],Q0),H,队列(X,Q,Q0))。
%%队列最后(+Queue0,+last,-queue)
%Queue0是队列,最后一个在后面
最后一个队列(队列(X,Q,[L | Q0]),L,队列(s(X),Q,Q0))。
做这样的事情,它的工作如预期:

..., empty_queue(Q), queue_last(Q, 999, Q_), writeln(Q_), ....
我得到

queue(s(0),[999|_3076],_3076)
同样有趣的是,如果我用这个片段观察
Q
的值:

empty_queue(Q), writeln(Q), queue_last(Q, 999, Q_), writeln(Q)
我得到:

queue(0,_3750,_3750)
queue(0,[999|_3758],[999|_3758])
我想应该是这样的,因为差异导致空列表,所以它们在某种程度上是等价的

问题是,在发出命令之后

queue_last(Q, 999, Q_)
我不能重复使用
Q
来创建
Q\uu
,例如:

empty_queue(Q), queue_last(Q, 999, Q_), queue_last(Q, 888, Q__)
因为
queue_last(queue(X,Q[L|Q0]),L,queue(s(X),Q,Q0))的绑定失败。

L = 888, L = 999 (tries to be both)
我怎样才能解决这个问题?有解决办法吗?(始终使用差异列表)

我不能重复使用
Q
来创建
Q\uuu

这是因为您必须使用“线程化”的新结构,您称之为
Q
。旧的
Q
是燃烧器,必须丢弃。它不再正确地描述“差异列表”

?-空队列(Q1),
最后一个队列(Q1、999、Q2),
最后排队(第二季度、第888季度、第三季度)。
Q1=队列(0、[999888|||12414]、[999888|12414]),%
Q2=队列(s(0),[999888||||12414],[888||12414]),%
Q3=队列(s(s(0)),[999888 | 14714],_14714)。%正确的,有效的
清空队列(Q1)
呼叫后,这是
Q1

队列
├── arg 0:0
├── arg 1:-----+-->
|              |
└── arg 2:----+
最后一次(Q1、999、Q2)呼叫后,这是
Q1
Q2

Q1
(无效)

队列
├── arg 0:0
├── arg 1:-----+->[|]
|              |     / \
|              |  999  
|              |
└── arg 2:----+
Q2
(有效)

队列
├── arg 0:s(0)
├── arg 1:----------->[|]
|                    / \
|                 999  
|                          ^
|                          |
└── arg 2:----------------+
最后一次(Q2、888、Q3)呼叫后,这是
Q1
Q2
Q3

Q1
(无效)

队列
├── arg 0:0
├── arg 1:-----+->[|]
|              |     / \
|              |  999   [|]
|              |       /   \
└── arg 2:---+888
Q2
(无效)

队列
├── arg 0:s(0)
├── arg 1:----------->[|]
|                    / \
|                 999  [|][|]
|                    / \
|                 999  [|]
|                      /  \              
|                   888   
|                                ^
|                                | 
└── arg 2:----------------------+

无法重新分配Prolog变量。你不能重复使用它们。我不知道调用变量“burned”是否有很大帮助,它们不是burned,而是绑定到一个具体的值

不要使用“write”和friends,除非您正在进行一些复杂的打印样式调试。在顶层进行尝试,无论如何你都会把所有内容打印出来。下面是如何使用此队列实现。请注意,我使用的是
Q0
Q1
Q2
,等等,因为当有多个下划线时,我很难计数下划线

a
,然后在队列末尾的
b

?-空队列(Q0),队列最后一个(Q0,a,Q1),队列最后一个(Q1,b,Q2)。
Q0=队列(0[a,b|u 15096],[a,b|u 15096]),
Q1=队列(s(0),[a,b|25096],[b|25096]),
Q2=队列(s(s(0)),[a,b|u 15096],_15096)。
a
排队,然后将
b
排队,然后弹出您排队的第一个值(顺序):

?-空队列(Q0),队列最后一个(Q0,a,Q1),队列最后一个(Q1,b,Q2),
队列头(Q2,弹出,Q3)。
Q0=队列(0[a,b|u 17772],[a,b|u 17772]),
Q1=队列(s(0),[a,b|u 17772],[b|u 17772]),
Q2=队列(s(s(0)),[a,b | u 17772],_17772),
砰砰的一声,
Q3=队列(s(0),[b | _17772],_17772)。
向前推两次,然后弹出(顺序):

?-空队列(Q0)、队列头(Q1,x,Q0)、队列头(Q2,y,Q1),
队列头(Q2,弹出,Q3)。
Q0=队列(0,_21688,_21688),
Q1=Q3,Q3=队列(s(0),[x | 21688],21688),
Q2=队列(s(s(0)),[y,x | u 21688],_21688),
弹出=y。

我在你问题下方的评论中链接的答案(这里又是:)详细解释了这是如何工作的。它还有到其他相关Q/a等的链接。

好的,我明白了,如果我想使用“烧掉的”一个队列两次,以便从初始队列生成两个不同的队列,那么有什么解决方法吗?@但是为什么你可以用重命名(新鲜)变量创建深度副本,即新分配的“空单元格”。但是如果我要复制一个列表,为什么我不应该首先使用append?@但是为什么“差异列表”的想法是不复制t0处存在的结构,而只是“在末尾追加”,在尚未定义的位置增长结构。但是,为了保持差异列表中名为tip和fin的变量的“差异列表”,您必须切换到新的上下文。这通常是通过尾部递归调用完成的。在使用“队列”的代码中,这是模糊的,因为它看起来像是面向对象的或功能性的,但实际上不是,您不能使用“旧队列”。@但是为什么如果您使用
append/2
,那么
t0
处存在的结构将被完全定义(在fin处没有空单元格),并且您可以永远保留它,但它也会被删除