0
votes

I'm new to Prolog and i'm trying to create a knowledge base consisting of a list through multiple appends. Is it possible? If from the command line i write:

append([a,b],[c,d],L0), append(L0,[e,f],L1).

the output is:

L0 = [a, b, c, d],
L1 = [a, b, c, d, e, f].

If i write the same code in a .pl file it says:

Full stop in clause-body? Cannot redefine ,/2

Is there a way to tell Prolog to apply the appends and then use L1 as knowledge base?

Edit: I found a way to do it:

list(L1) :- append([a,b],[c,d],L0), append(L0, [e,f], L1).

But this way, every time i call list(L) it re-creates the list from scratch. Is there a better way to do it, or this is the way to go?

2

2 Answers

1
votes

Your edit answers the question, that is in general the way to do it.

However, if you wish to save the result of the predicate for performance reasons (i.e. not having to run the several appends again), you can use the asserta/1 or assertz/1 predicates. For instance, lets say that you have a main predicate that you're running, and you wish to do your append procedure and save that in a saved_list/1 predicate, you can do this:

main :- 
    append([a,b],[c,d],L0), 
    append(L0,[e,f],L1), 
    asserta(saved_list(L1)).

(you can try this out on the command-line if you wish to play around with it)

Now, if you run saved_list(X) later, X will unify with [a, b, c, d, e, f] without having to run the appends. If saved_list/1 is already defined somewhere in the code, you have to declare it as dynamic.

However, a warning: using the various assert and retract predicates is generally discouraged because they are side-effects. If improperly used, they can make code much harder to understand and reason about and can lead to subtle bugs.

In addition, dynamic predicates are not as fast in general as hard-coded ones (i.e. hard-coding the predicate as saved_list([a,b,c,d,e,f]). makes calling it faster than if you have asserted it dynamically). Using it to cache values so that you don't have to calculate them over and over again (i.e. essentially using memoization) is generally ok, but it still should be avoided if possible.

Unless the lists you are appending are huge, I would recommend going with the solution that you provided. Using assert is an unnecessary boondoggle unless doing the appends take a very long time.

0
votes

what do you want? I do not understand.

Your predicate works fine.