Reputation: 421020
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.)
Upvotes: 14
Views: 13338
Reputation: 14468
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.
Upvotes: 13
Reputation: 56772
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.
Upvotes: 3