tags:

views:

69

answers:

2
+4  Q: 

Prolog Constants

Is there any way to define constants in prolog?

I'd like to write something like

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

predicate(L) :- append(list1, list2, L).

The work-around I'm using now is

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

predicate(L) :-
    list1(L1),
    list2(L2),
    append(L1, L2, L).

but it's a bit clumsy to bind a "useless" variable like this every time I need to access the constant.

Another (even uglier) work around I suppose, would be to include cpp in the build-chain.

(In my actual application, the list is a large LUT used in many places.)

+6  A: 

I don't think you can do that in 'pure' Prolog (though some implementations may let you do something close, for example ECLiPSe has shelves).

The reason is:

1) You can't write things like

list1 :- [4, 5, 6].

or

list1 = [4, 5, 6].

Because right hand side and left hand side are both grounds terms which don't match.

2) You can't write things like

List1 :- [4, 5, 6].

or

List1 = [4, 5, 6].

because the left hand side is now a variable, but variables are only allowed in predicate heads/bodies.

What you could do is to define a multi-option predicate like:

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

and then retrieve all its values with bagof (or similar predicates):

predicate(L) :-
    bagof(ML, myList(ML), MLs).        
    concat(MLs, L).

MLs is the list of all ML values that satisfy myList(ML) and of course concat concatenates a list of lists.

Mau
I agree with your answer, and think that using ground terms like `p([1,2,3]).` or 0-arity terms like `x.` is generally the way to go to define _global_ constants in PROLOG, and to use such terms when local in the definition of predicates, which could include something like `List1 = [4, 5, 6]` as a subgoal (as you mentioned).
sharky
+1  A: 

No, you can't do that in Prolog, and defining it via a predicate is the sensible thing to do.

Or better, encapsulate your lookup function in a predicate.

That said, if you really want to use preprocessing there is term_expansion/2, but it can make your code unreadable and messy if you are not careful.

You could also look into extensions of Prolog that include function notation (functional logic languages like Mercury). But these are even more exotic than Prolog.

starblue