我必须在Prolog中以点符号形式表示[[fruits],[ ] ]
,下面是我如何做到的,但有些事情告诉我这是错误的,因为我也扩展了[[ ]]
,这是不正确的?< / p>
.([fruits],[[ ]] )
.(.(fruits, []),.([],[])
答案 0 :(得分:7)
除了Willem所写的内容之外,您始终可以使用write_canonical/1
来获取任何字词的规范表示形式。
例如,在您的情况下:
| ?- write_canonical([[fruits],[ ] ]). '.'('.'(fruits,[]),'.'([],[]))
这解决了任务,并显示您已正确扩展列表[[]]
。
特别是,我们有:
| ?- write_canonical([[]]). '.'([],[])
这是正确的:这是一个包含单个元素的列表,[]
由'.'/2
项的第一个参数指示。由于它是 only 元素,因此第二个参数也是[]
。
答案 1 :(得分:5)
嗯,./2
就是 Lisp 中的cons
。它包含两个参数: head 元素和 tail 。尾部可以是空列表[]
,也可以是其他cons
。
让我们先来看看我们要转换的术语:
X = [ [fruits] , [] ]
我们看到的是一个包含两个元素的外部列表(我们现在将忽略这些元素)。这意味着我们有一个像:
这样的结构X = .( Item1, .( Item2, []) ).
当然,我们仍然需要填写Item1
和Item2
。 Item2
并不难:它是空列表[]
所以:
Item2 = [].
另一方面, Item1
是一个包含一个元素的列表,因此结构为:
Item1 = .( Item11, [] ).
使用Item11
该子列表的项目。该项目为fruits
,因此意味着:
Item11 = fruits.
如果我们将这些全部放在一起,我们会得到:
X = .( .(fruits,[]), .([],[]) ).
如果我们在GNU-Prolog(gprolog
)中输入,我们得到:
$ gprolog
GNU Prolog 1.4.5 (64 bits)
Compiled Feb 5 2017, 10:30:08 with gcc
By Daniel Diaz
Copyright (C) 1999-2016 Daniel Diaz
| ?- X = .( .(fruits,[]), .([],[]) ).
X = [[fruits],[]]
yes
gprolog
因此可以作为验证工具,因为它会将点符号转换为列表的语法糖。
答案 2 :(得分:2)
最初在prolog中没有[]
,vector
总是使用.
构建。
以下是David Warren撰写的1979年论文中的一个例子[* 36&#39;脚注]:
([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]
上面的工作在yap,eclipse,gprolog,xsb。 但它在swipl中不起作用(见附录)。
文章中提供的 concatenated
与append
的典型 - 现代prolog实现完全相同,但名称不同,末尾有不同的标记。
一般模式是每个元素都通过.
与它的邻居分开。
最后一个元素是表示结束的标记。在沃伦的例子中,nil
是表示结束的标记。使用nil
似乎是一种惯例,但不是必需的。 prolog的后续开发取代了使用nil
作为结束的标记,并使用[]
作为结束的标记。
Warren的开创性示例可以最低限度地重写,以使用[]
代替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]
沃伦继续......
...其中列表是原子&#39; nil&#39;或者由...形成的术语 二元仿函数&#39;。&#39;第二个参数是一个列表...我们写的是 functor作为
right- 关联中缀运算符,以便for 例如,提到的第一个列表[ed:(a.b.c.d.nil)
]是 相当于标准格式.(a,.(b,.(c,.(d,nil))))'
Warren提供了这个例子......
([user]) .
list(nil) .
list(.(X,L)) :- list(L) .
%^D
测试和演示......
/*
((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年前(list(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
......我不知道如何解决这些问题。
当沃伦写道......
我们把仿函数写成一个
右 - 关联中缀运算符,以便......
......我认为他指的是序言xfy
的这个特殊而有用的特征......
([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&#39;脚注] --- https://www.era.lib.ed.ac.uk/bitstream/handle/1842/6648/Warren1978.pdf
不要尝试在swipl中使用.
或[]
,
.
和[]
都不是所描述的功能。
我报告了关于.
的错误信息;
假设不符合传统
和标准的prolog系统是有意义的;
它似乎不是。
https://github.com/SWI-Prolog/issues/issues/55
swipl的作者提出使用term_expansion
的建议,但term_expansion
和goal_expansion
的使用都不能解决问题
以下基本兼容性问题。
/*
(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(term_expansion?!??!)或者对prolog一致性不感兴趣或者对建立供应商锁定感兴趣。