List 在prolog中转换为点表示法
我必须在Prolog中用点符号形式表示List 在prolog中转换为点表示法,list,syntax,prolog,List,Syntax,Prolog,我必须在Prolog中用点符号形式表示[[fruits],]],下面是我是如何做到的,但有些东西告诉我这是错误的,因为我也扩展了[[]],这是错误的吗 .([fruits],[[ ]] ) .(.(fruits, []),.([],[]) 嗯,/2就是Lisp中的cons。它包含两个参数:元素的头部和尾部。尾部可以是空列表[],也可以是另一个cons 让我们先看看我们必须转换的术语: X = [ [fruits] , [] ] 我们看到的是一个包含两个元素的外部列表(我们现在将忽略这些元素
[[fruits],]]
,下面是我是如何做到的,但有些东西告诉我这是错误的,因为我也扩展了[[]]
,这是错误的吗
.([fruits],[[ ]] )
.(.(fruits, []),.([],[])
嗯,
/2
就是Lisp中的cons
。它包含两个参数:元素的头部和尾部。尾部可以是空列表[]
,也可以是另一个cons
让我们先看看我们必须转换的术语:
X = [ [fruits] , [] ]
我们看到的是一个包含两个元素的外部列表(我们现在将忽略这些元素)。这意味着我们有这样一个结构:
X = .( Item1, .( Item2, []) ).
现在我们当然还需要填写Item1
和Item2
<代码>项目2不难:它是空列表[]
,因此:
Item2 = [].
另一方面,Item1
是一个包含一个元素的列表,因此结构为:
Item1 = .( Item11, [] ).
使用Item11
该子列表的项。该项是水果
,这意味着:
Item11 = fruits.
如果我们将这些放在一起,我们将获得:
X = .( .(fruits,[]), .([],[]) ).
如果我们在GNU Prolog(gprolog
)中输入它,我们会得到:
gprolog
因此可以作为进行验证的工具,因为它会将点符号转换为列表的语法糖。除了Willem编写的内容外,您还可以始终使用write\u canonical/1
来获得任何术语的规范表示
例如,在您的情况下:
| ?- write_canonical([[fruits],[ ] ]).
'.'('.'(fruits,[]),'.'([],[]))
没错:这是一个包含单个元素的列表,它是
[]
,如术语的第一个参数所示。/2
术语。由于它是唯一的元素,第二个参数也是[]
最初在prolog中没有[]
,而向量总是使用
构造的
以下是大卫·沃伦(David Warren)[*36'脚注]1979年发表的一篇论文中的一个例子:
([user]) .
:- (op(1,'xfy','.')) .
concatenated(nil,L,L) .
concatenated((X.L1),L2,(X.L3)) :- concatenated(L1,L2,L3) .
%^D
测试和演示
/*
((concatenated((nil),(nil),Z)) , Z == (nil)) .
((concatenated((a.b.nil),(c.d.nil),Z)) , Z == (a.b.c.d.nil)) .
*/
?- ((concatenated((nil),(nil),Z)) , Z == (nil)) .
%@ Z = nil
?- ((concatenated((a.b.nil),(c.d.nil),Z)) , Z == (a.b.c.d.nil)) .
%@ Z = [a,b,c,d|nil]
/*
((List = (nil)) , (list(List))) .
(\+ ((List = (a)) , (list(List)))) .
((List = (a.nil)) , (list(List))) .
(\+ ((List = (nil.a)) , (list(List)))) .
((List = (nil.nil)) , (list(List))) .
*/
?- ((List = (nil)) , (list(List))) .
%@ List = nil
?- (\+ ((List = (a)) , (list(List)))) .
%@ true
?- ((List = (a.nil)) , (list(List))) .
%@ List = [a|nil]
?- (\+ ((List = (nil.a)) , (list(List)))) .
%@ true
?- ((List = (nil.nil)) , (list(List))) .
%@ List = [nil|nil]
上面的代码在yap、eclipse、gprolog和xsb中工作。
但是,它在swipl中不起作用(见附录)
本文介绍的
串联与现代典型的附加prolog实现完全相同,但名称不同,结尾标记不同
一般的模式是每个元素通过
与其相邻元素分离
最后一个元素是表示结束的标记。在沃伦的例子中,nil
是表示结束的标记。使用nil
似乎是一种惯例,但不是一种要求。prolog的后续开发将使用nil
作为结束标记替换为使用[]
作为结束标记
沃伦的开创性例子可以用[]
而不是nil
进行最低限度的改写
([user]) .
((append([] , L , L))) .
(
(append((X.L1) , L2 , (X.L3)))
)
:-
(
(append(L1 , L2 , L3))
)
.
%^D
/*
((append(([]) , ([]) , Z)) , (Z == [])) .
((append((a.b.[]),(c.d.[]),Z)) , Z == (a.b.c.d.[])) .
((append((a.b.[]),(c.d.[]),Z)) , Z == [a,b,c,d]) .
((append(([a,b]),([c,d]),Z)) , Z == [a,b,c,d]) .
*/
?- ((append(([]) , ([]) , Z)) , (Z == [])) .
%@ Z = []
?- ((append((a.b.[]),(c.d.[]),Z)) , Z == (a.b.c.d.[])) .
%@ Z = [a,b,c,d]
?- ((append((a.b.[]),(c.d.[]),Z)) , Z == [a,b,c,d]) .
%@ Z = [a,b,c,d]
?- ((append(([a,b]),([c,d]),Z)) , Z == [a,b,c,d]) .
%@ Z = [a,b,c,d]
沃伦继续说
。。。其中列表是原子“nil”或由
二元函子“.”,其第二个参数是列表。。。我们写
函子作为右关联中缀运算符,以便
例如,提到的第一个列表[ed:(a.b.c.d.nil)
]是
相当于标准格式(a,(b,(c,(d,nil))”
沃伦提供了这个例子
([user]) .
list(nil) .
list(.(X,L)) :- list(L) .
%^D
测试和演示
/*
((concatenated((nil),(nil),Z)) , Z == (nil)) .
((concatenated((a.b.nil),(c.d.nil),Z)) , Z == (a.b.c.d.nil)) .
*/
?- ((concatenated((nil),(nil),Z)) , Z == (nil)) .
%@ Z = nil
?- ((concatenated((a.b.nil),(c.d.nil),Z)) , Z == (a.b.c.d.nil)) .
%@ Z = [a,b,c,d|nil]
/*
((List = (nil)) , (list(List))) .
(\+ ((List = (a)) , (list(List)))) .
((List = (a.nil)) , (list(List))) .
(\+ ((List = (nil.a)) , (list(List)))) .
((List = (nil.nil)) , (list(List))) .
*/
?- ((List = (nil)) , (list(List))) .
%@ List = nil
?- (\+ ((List = (a)) , (list(List)))) .
%@ true
?- ((List = (a.nil)) , (list(List))) .
%@ List = [a|nil]
?- (\+ ((List = (nil.a)) , (list(List)))) .
%@ true
?- ((List = (nil.nil)) , (list(List))) .
%@ List = [nil|nil]
现在40年前的(列表(L))的实现,
不符合现代人对“逻辑”程序的期望
% does it provide a useful answer in the general case ?
?- ((List = _) , (list(List))) .
%@ List = nil ? ;
%@ List = [_A|nil] ? ;
%@ List = [_A,_B|nil] ? ;
%@ List = [_A,_B,_C|nil] ? ;
%@ List = [_A,_B,_C,_D|nil] ? ;
%@ !! etc ... non-terminating !!
%@ ^CAction (h for help): a
% is it steadfast ?
?- ((list(List)) , (List = (nil))) .
%@ List = nil ? ;
%@ !! hang , non-terminating !!
%@ ^CAction (h for help): a
。。。我不知道如何解决这些问题
当沃伦写
我们把函子写成一个函数
右关联中缀运算符,以便
。。。我认为他指的是prologxfy
的这个独特而有用的特性
([user]) .
:- ((op(10'1,'xfy','~'))) .
%^D
/*
(((Left ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left == a) , (Rest == (b~c~d~e))) .
(((Left_1 ~ Left_2 ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left_1 == a) , (Left_2 == b) , (Rest == (c ~ d ~ e))) .
*/
?- (((Left ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left == a) , (Rest == (b~c~d~e))) .
%@ Left = a,
%@ Rest = b~c~d~e
?- (((Left_1 ~ Left_2 ~ Rest) = (a ~ b ~ c ~ d ~ e)) , (Left_1 == a) , (Left_2 == b) , (Rest == (c ~ d ~ e))) .
%@ Left_1 = a,
%@ Left_2 = b,
%@ Rest = c~d~e
有理由期望yfx
运算符的行为相反;
而xfy
允许从左侧抓取元素,忽略右侧的其余元素,
也许yfx
允许您从右侧抓取元素,而忽略左侧的其余元素
:- ((op(10'1,'yfx','~'))) .
%^D
/*
(((Rest ~ Right) = (a ~ b ~ c ~ d ~ e)) , (Rest == a~b~c~d) , (Right == e)) .
(((Rest ~ Right_2 ~ Right_1) = (a ~ b ~ c ~ d ~ e)) , (Rest == a ~ b ~ c) , (Right_2 == d) , (Right_1 == e)) .
*/
?- (((Rest ~ Right) = (a ~ b ~ c ~ d ~ e)) , (Rest == a~b~c~d) , (Right == e)) .
%@ Rest = a~b~c~d,
%@ Right = e
?- (((Rest ~ Right_2 ~ Right_1) = (a ~ b ~ c ~ d ~ e)) , (Rest == a ~ b ~ c) , (Right_2 == d) , (Right_1 == e)) .
%@ Rest = a~b~c,
%@ Right_1 = e,
%@ Right_2 = d
[*36'脚注]--
附录
不要费心在swipl中玩
或[]
,
和[]
都不能正常工作
我向swipl报告了一个关于
的bug;
假设不符合传统标准
标准prolog系统也很有趣;
看来并非如此
swipl的作者建议使用术语扩展
,但是无论是术语扩展
还是目标扩展
都不能解决问题
以下是基本的兼容性问题
/*
(a.b.[]) =[a,b] .
A ={ foo:a.b.nil } .
[a,b|[c,d]] = [a,b,..[c,d]] .
*/
$ yap
+ yap
YAP 6.2.2 (x86_64-linux): Wed Sep 7 07:48:47 PDT 2016
MYDDAS version MYDDAS-0.9.1
?- (a.b.[]) =[a,b] .
%@ yes
?- A ={ foo:a.b.nil } .
%@ A = {[foo:a,b|nil]}
?- [a,b|[c,d]] = [a,b,..[c,d]] .
%@ yes
?- (halt) .
% YAP execution halted
$ swipl
+ swipl
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.27)
Copyright (c) 1990-2016 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is LGPL free software,
and you are welcome to redistribute it under certain conditions.
For help, use ?- help(Topic). or ?- apropos(Word).
?- (a.b.[]) =[a,b] .
ERROR: Type error: `dict' expected, found `a' (an atom)
?- A ={ foo:a.b.nil } .
ERROR: Type error: `dict' expected, found `a' (an atom)
?- [a,b|[c,d]] = [a,b,..[c,d]] .
ERROR: Syntax error: Operator expected
ERROR: [a,b|[c,d]] = [a,b,.
ERROR: ** here **
ERROR: .[c,d]] .
?- (end_of_file) .
% halt
。。。向我建议,也许swipl的作者不太了解prolog(术语扩展?!!),或者对prolog的一致性不感兴趣,或者对建立供应商锁定感兴趣。谢谢大家,这非常有用,不确定是否需要更新。为了让它正常工作,我必须使用` write_term([[fruits],][]],[dotlists(true)]。`请参见:如果您有一个预期的答案,您可以始终使用相等/统一进行检查:
((fruits,[]),([],[])这是简在书中解释的第二件事。您可以通过调用swipl--traditional
重新激活旧模式。这里没有关于供应商锁定的阴谋。