Prolog 编写谓词以添加原子

Prolog 编写谓词以添加原子,prolog,Prolog,我必须编写一个谓词来执行以下工作: ?- cat(north,south,X). X = northsouth ?- cat(alley,'91',Y). X = alley91 ?-cat(7,uthah,H). Bad Input H = H 请帮助..atom\u代码/2在atom和代码列表之间转换是ISO批准的谓词。当您有两个对应于前两个参数的列表时,append/3(唉,不是ISO批准的,但每个序言中都有AFAIK)将获得对应于第三个参数的列表

我必须编写一个谓词来执行以下工作:

  ?- cat(north,south,X).
  X = northsouth

  ?- cat(alley,'91',Y).
  X = alley91

  ?-cat(7,uthah,H).
    Bad Input
    H = H

请帮助..

atom\u代码/2在atom和代码列表之间转换是ISO批准的谓词。当您有两个对应于前两个参数的列表时,append/3(唉,不是ISO批准的,但每个序言中都有AFAIK)将获得对应于第三个参数的列表,然后,将该列表转换为atom

请注意,虽然append/3是一个“纯”Prolog谓词,可以使用任何实例化模式,但atom_code/2要求至少实例化一个参数。这里是cat/3的一个SWI Prolog实现,更一般地说是“工作”。我希望它能激励你阅读更多关于序言的内容

ac(X,Xs) :-  when((ground(X);ground(Xs)), atom_codes(X,Xs)).
cat(X,Y,Z) :- maplist(ac, [X,Y,Z],[Xs,Ys,Zs]), append(Xs,Ys,Zs).
编辑

正如@false所指出的,关于append/3,我错了。现在我将尝试更好地理解append/3的作用。。。哇,一个如此简单的谓词,如此丰富的行为

atom_concat_redefined(A1, A2, A3) :-
   ( nonvar(A1) -> atom_chars(A1, Chs1) ; true ),
   ( nonvar(A2) -> atom_chars(A2, Chs2) ; true ),
   ( nonvar(A1), nonvar(A2) -> true ; atom_chars(A3, Chs3) ),
   append(Chs1, Chs2, Chs3),
   atom_chars(A1, Chs1),
   atom_chars(A2, Chs2),
   atom_chars(A3, Chs3).
此定义在符合标准的实现(如SICStus或GNU)中产生相同的错误-除了性能之外,不应有其他差异。要比较错误,请使用目标:

| ?- catch(atom_concat_redefined(A,B,abc+1), error(E,_), true).
E = type_error(atom,abc+1) ? ;
no

请注意
错误(E,41;
中的下划线,它隐藏了实现定义的差异。在这个参数中,实现提供了额外的信息,特别是,它们将揭示
atom\u chars/2
atom\u concat/3
产生了错误。

您的谓词正在写出所需的结果,但也显示了,例如,
X=X
,因为第三个参数没有任何用途,并且您没有使用它(因此,您的谓词子句中的参数有
。)因此,
cat(X,G):-…
。还要注意的是,在上次写入后,您需要使用
nl
来输出新行。我必须将其设置为三元,不能将其设置为二元。这个问题不会消失,因此需要寻求帮助。然后,不要使用
write
,而是使用第三个参数作为结果,如给定的答案所示。请参阅序言。
append/3
不适用于任何实例化模式。例如,请考虑:
append(Xs[a],Xs)
哪个应该失败,但会循环。另外
append/3
要求实例化第一个或最后一个参数(实际上,比这稍微多一些)。否则它不会终止。@false:那么Xs作为属性变量呢?我们能以某种方式控制行为吗?可能有用吗?所有这些都在30年前在MU/NU Prolog中进行了实验,我敢说,结果并不是很令人鼓舞:到处都在奋斗目标。我不是不终止的朋友,但它经常出现在易陷入困境。如果你真的想解决这个问题,你就必须学习:一般的关联统一-非常难以理解和实现。没有办法(到今天为止)将其应用到Prolog的超高速DCG解析中……但问题可能在等着你:-)在这个方向上的另一个尝试是Prolog III中的一些结构,neamoins它没有做左递归…谢谢。它在SWI Prolog中工作。但在我的编译器中,它给出了类似于-Undefined谓词的错误:atom_chars/2。任何预定义的谓词都不能使用,这使得编写这样一个只能使用一些基本Prolog命令的函子变得复杂。请帮忙。@ela:这是什么样的系统?你有什么与atom相关的内置程序?这是NU Prolog。我学习这种语言的来源是使用这种编译器进行教学。我正在SWI-Prolog和NU-Prolog上尝试我的代码。许多代码似乎在SWI Prolog上工作,但在NU Prolog上失败。请帮帮我。@ela:天哪!这个系统在过去的四分之一世纪里没有更新过!使用
name/2
代替
atom\u chars/2
。这不是100%正确,但我认为这是你能得到的。或者使用
atomToString/2
,但这一个会延迟。不确定你应该做什么。可能只是:删除非AR部分,先声明
atomToString
3x,然后追加。