Prolog 序言常数

Prolog 序言常数,prolog,Prolog,有没有办法在prolog中定义常量 我想写一些像这样的东西 list1 :- [1, 2, 3]. list2 :- [4, 5, 6]. predicate(L) :- append(list1, list2, L). 我现在使用的工作环境是 list1([1, 2, 3]). list2([4, 5, 6]). predicate(L) :- list1(L1), list2(L2), append(L1, L2, L). 但每次我需要访问常量时,像这样绑定一

有没有办法在prolog中定义常量

我想写一些像这样的东西

list1 :- [1, 2, 3].
list2 :- [4, 5, 6].

predicate(L) :- append(list1, list2, L).
我现在使用的工作环境是

list1([1, 2, 3]).
list2([4, 5, 6]).

predicate(L) :-
    list1(L1),
    list2(L2),
    append(L1, L2, L).
但每次我需要访问常量时,像这样绑定一个“无用”变量有点笨拙

我认为另一个(甚至更丑陋的)解决方法是在构建链中包含cpp


(在我的实际应用程序中,列表是一个在许多地方使用的大型LUT。)

我认为在“纯”Prolog中无法做到这一点(尽管有些实现可能允许您完成某些操作,例如ECLiPSe有工具架)

原因是:

1) 你不能写这样的东西

因为右手边和左手边都是不匹配的接地术语

2) 你不能写这样的东西

因为左侧现在是一个变量,但变量只允许在谓词头/体中使用

您可以定义一个多选项谓词,如:

myList([1, 2, 3]).
myList([4, 5, 6]).
然后使用bagof(或类似谓词)检索其所有值:


MLs
是满足
myList(ML)
的所有
ML
值的列表,当然
concat
连接列表。

不,在Prolog中不能这样做,通过谓词定义它是明智的做法

或者更好,将查找函数封装在谓词中

这就是说,如果您真的想使用预处理,有
术语扩展/2
,但如果您不小心,它会使您的代码变得不可读和混乱


您还可以研究Prolog的扩展,其中包括函数表示法(函数逻辑语言,如)。但是这些比Prolog更奇特。

我同意你的答案,并认为使用基本术语,如
p([1,2,3])。
或0-arity术语,如
x。
通常是在Prolog中定义全局常量的方法,并且在谓词定义中使用局部术语,这可能包括类似于
List1=[4,5,6]
的子目标(如您所述)。bagof语句的末尾不应该有逗号吗?我不能把MLs放在一个单子上。这不是一个解决办法。这叫做事实声明。如果
list1/1
的参数是
[1,2,3]
,则表明它是连续目标。prolog中没有变量,因此可以假设每个“值”(原子或术语)都是常量,每个“变量”(值名称)都是非确定性常量。每个“变量”(例如
L1
)甚至可以包含
(1+2*3)
,而且它永远不会被解释,因为这是一个术语(类似
(1+(2*3))
,还有一个事实
(7是(1+(2*3))。
。当您将
list1
作为append的参数传递时,它被解释为atom。您可以定义
myappend(list1,list2),[1,2,3,4,5,6])。
我使用事实声明作为没有常量的解决方法。
list1 = [4, 5, 6].
List1 :- [4, 5, 6].
List1 = [4, 5, 6].
myList([1, 2, 3]).
myList([4, 5, 6]).
predicate(L) :-
    bagof(ML, myList(ML), MLs),        
    concat(MLs, L).