在prolog中转换为点表示法

时间:2017-05-22 11:46:51

标签: list syntax prolog

我必须在Prolog中以点符号形式表示[[fruits],[ ] ],下面是我如何做到的,但有些事情告诉我这是错误的,因为我也扩展了[[ ]],这是不正确的?< / p>

.([fruits],[[ ]] )

.(.(fruits, []),.([],[])

3 个答案:

答案 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, []) ).

当然,我们仍然需要填写Item1Item2Item2并不难:它是空列表[]所以:

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中不起作用(见附录)。

文章中提供的

concatenatedappend的典型 - 现代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_expansiongoal_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一致性不感兴趣或者对建立供应商锁定感兴趣。