Prolog: Convert constant with parentheses to string - prolog

I have question about Prolog. When I have the constant e.g. fib(7) and I want to convert it to a string with atom_codes(fib(7), A) I get the error, that for fib(7) a non numeric atom is expected.
Obviously the parentheses are the problem. What can i do?

You have a couple of misunderstandings. fib(7) is not a "constant". It's a "term". It is also not an "atom". atom_codes (as its name implies) converts an atom to a list of character codes.
I'll give you some ideas on how to handle this problem, which I would have indicated in the comments, but it's much too long of a hint to do so. :)
You could write a predicate and use the =../2 to break the term down. =../2 unifies a term as its first argument with a list as its second where the functor of the term is the first element of the list, and the remaining elements are the arguments in the term.
If you know you are dealing with simple terms, then your predicate could look like this:
term_codes(Term, Codes) :-
Term =.. [Functor | Arguments],
atom_codes(Functor, Codes),
( Arguments = []
-> true % Term is a simple atom
; % Arguments is a list of atoms or more complex terms
% For a simple argument list, you can use atom_list_concat
).
See Prolog list to comma separated string for an example of using atom_list_concat and, from there, you can use atom_codes for a list.
This is just my first thought on this problem. For now I'll leave the filling in of the details in the above if Arguments is not empty. If you are going to assume always a single, atomic argument, the predicate is very simple. However, if you can have an arbitrary number of arguments for your Term, then you'll need to process it as a list and concatenate the results of atom_codes for each argument and include a code for comma (,) in between each sequence of atom codes. The predicate becomes even more complex if your Term can be compound (e.g., foo(1, bar(2, 3))`). I'm not sure which it is since it hasn't been specified in the question.
Using your fib(7) example, here's the concept:
fib(7) =.. [fib, [7]]
atom_codes(fib, [102, 105, 98])
atom_codes(7, [55]),
atom_codes('(', [40]),
atom_codes(')', [41]),
% result would be: [102, 105, 98, 40, 55, 41])

Related

Printing first letter of an atom Prolog

Print the first letter of two atoms in a list. I can't even get the first letter of one of the two atoms in the list to print.
grab_letter([],[]).
grab_letter([A],[B]) :- A = [First|_], B = [Second|_].
?- grab_letter([apple,pie]).
true ?
How do I get it to print "a"?
The ISO Prolog standard specifies a sub_atom/5 built-in predicates that can decompose an atom into a sub-atom. The first argument is the atom, the second argument is the number of characters before the sub-atom, the third argument is the length of the sub-atom, the fourth argument is the number of characters after the sub-atom, and the fifth argument is the sub-atom. For example:
| ?- sub_atom(apple, 0, 1, _, First).
First = a
yes
| ?- sub_atom(pie, 0, 1, _, First).
First = p
yes
You can call this predicate from your code that processes the list containing the atoms. Can you give it a try and edit your question with the updated code?
Using in alternative the also standard atom_chars/2 predicate, as suggested in a comment, is not a good idea as it results in creating a temporary list (that will eventually be garbage-collected) just to access the first character.

List with if - plus and minus

I should create a list with integer.It should be ziga_arnitika(L,ML).Which take L list (+) integer and will return the list ML only (-) integer the even numbers of list L.
Warning:The X mod Y calculates X:Y.
Example: ziga_arnitika([3,6,-18,2,9,36,31,-40,25,-12,-5,-15,1],ML).
ML =[-18,-40,-12]
i know for example with not list to use if but not with lists,what i did is..:
something(12) :-
write('Go to L).
something(10) :-
write('Go to Ml).
something(other) :-
Go is other -10,
format('Go to list ~w',[ML]).
You want to compute a list with elements satisfying some properties from a given list. Lists in Prolog have a very simple representation. The empty list is represent by []. A non-empty list is a sequence of elements separated by a comma. E.g. [1,2,3]. Prolog also provides handy notation to split a list between its head (or first element) and its tail (a list with the remaining arguments):
?- [1,2,3] = [Head| Tail].
Head = 1,
Tail = [2, 3].
Walking a list (from its first element to its last element) can be done easily using a simple recursive predicate. The trivial case is when a list is empty:
walk([]).
If a list is not empty, we move to the list tail:
walk([Head| Tail]) :- walk(Tail).
However, if you try this predicate definition in virtually any Prolog system, it will warn you that Head is a singleton variable. That means that the variable appears once in a predicate clause. You can solve the warning by replacing the variable Head with an anonymous variable (which we can interpret as "don't care" variable). Thus, currently we have:
walk([]).
walk([_| Tail]) :- walk(Tail).
We can try it with our example list:
?- walk([1,2,3]).
true.
Prolog being a relational language, what happens if we call the walk/1 predicate with a variable instead?
?- walk(List).
List = [] ;
List = [_4594] ;
List = [_4594, _4600] ;
List = [_4594, _4600, _4606]
...
Now back to the original problem: constructing a list from elements of other list. We want to process each element of the input list and, if it satisfies some property, adding it to the output list. We need two arguments. The simple case (or base case) is again when the input list is empty:
process([], []).
The general case (or recursive case) will be:
process([Head| Tail], [Head| Tail2]) :-
property(Head),
process(Tail, Tail2).
assuming a predicate property/1 that is true when its argument satisfies some property. In your case, being a even, negative integer. But not all elements will satisfy the property. To handle that case, we need a third clause that will skip an element that doesn't satisfy the property:
process([Head| Tail], List) :-
\+ property(Head),
process(Tail, List).
The \+/1 predicate is Prolog standard negation predicate: it's true when its argument is false.
Let's try our process/2 predicate it by defining a property/1 predicate that is true if the argument is the integer zero:
property(0).
A sample call would then be:
?- process([1,0,2,0,0,3,4,5], List).
List = [0, 0, 0] ;
false
We have successfully written a predicate that extracts all the zeros from a list. Note that our query have a single solution. If we type a ; to ask for the next solution at the prompt, the Prolog top-level interpreter will tell us that there are no more solutions (the exact printout depends on the chosen Prolog system; some will print e.g. no instead of falsebut the meaning is the same).
Can you now solve your original question by defining a suitable property/1 predicate?
Update
You can combine the two recursive clauses in one by writing for example:
process([Head| Tail], List) :-
( % condition
property(Head) ->
% then
List = [Head| Tail2],
process(Tail, Tail2)
; % else
process(Tail, List)
).
In this case, we use the Prolog standard if-then-else control construct. Note, however, that this construct does an implicit cut in the condition. I.e. we only take the first solution for the property/1 predicate and discard any other potential solutions. The use of this control construct also prevents using the process/2 predicate in reverse (e.g. calling it with an unbound first argument and a bound second argument) or using it to generate pairs of terms that satisfy the relation (e.g. calling it with both arguments unbound). These issues may or may not be significant depending on the property that you're using to filter the list and on the details of the practical problem that you're solving. More sophisticated alternatives are possible but out of scope for this introductory answer.

What does the following recursive Prolog call output?

I'm trying to learn prologue, but man am I having trouble.
I have an example below as well as what it outputs, and I'm clearly stuck on some concepts but not sure what.
output([]).
output([c|R]):- output(R), !, nl.
output([X|R]) :- output(R), write(X).
?- output([a,b,c,d,e]).
Answer:
ed
ba
true.
Correct me if I'm wrong, but here is what I understand so far...
When we call output([a,b,c,d,e]).
prologue looks for a solution using unification,
it tries output([]) and fails, so it proceeds to the second output([c|R]) which then passes the tail of the list recursively into output([c|R]) until it hits the base case of output([]).
Now I get confused...It then hits the cut which locks R to [] and c with a value of e? how does the output afterwards happens? I'm really confused.
I think you're having a fundamental misunderstanding of what Prolog is doing and what unification is about. In Prolog when you make a query such as output([a,b,c,d,e]). Prolog will start from the beginning of your asserted facts and predicates and attempt to unify this term (your query) with a fact or the head of a predicate.
Unification
We need to stop here for a moment and understand what unification is. In Prolog, the operator =/2 is the unification operator and can be used to query the unification of two terms, term1 = term2. This query will succeed if term and term2 can be successfully unified. How can they be successfully unified? This can happen if there is a binding of variables in term1 and term2 such that the terms become, essentially, identical (by "essentially" I mean they might differ only in syntactic representation but are truly identical when in canonical form - see details below on what that is).
Here are examples of unification attempts that fail. You can enter these at a Prolog prompt and it will show immediate failure.
a = e. % This fails because the atom `a` is different than the atom `e1`
% There are no variables here that can change this fact
foo(X) = bar(Y)
% This fails because the functor `foo` is different than
% the functor `bar`. There's no way to get these terms to match
% regardless of how the variables `X` or `Y` might be instantiated
foo(a, Y) = foo(b, Y)
% This fails because no matter how the variable `Y` is instantiated
% the 1st argument of `foo` just cannot match. That is, the atom
% `a` doesn't match the atom `b`.
foo(a, b, X) = foo(a, b)
% This fails because the `foo/3` and `foo/2` have a different
% number of arguments. No instantiation of the variable `X` can
% change that fact
[1,2] = [1,2,3] % Fails because a list of 2 elements cannot match a list of 3 elements
[] = [_|_] % Fails because the empty list cannot match a list of at
% least one element.
[a,b,c] = [x|T] % Fails, regardless of how `T` might be bound, because `[a,b,c]`
% is a list whose first element is `a`
% and `[x|T]` is a list whose first element is `x`. The
% atoms `a` and `x` do not and cannot match.
Here are examples of successful unifications. You can test these as well at a Prolog prompt and you should get success or, if variables are involved, get at least one solution showing binding of variables that causes it to succeed:
a = a. % Trivial case: an atom successfully unifies with itself
X = a. % Succeeds with `X` bound to `a`
foo(X) = foo(a). % Succeeds with `X` bound to `a`
[a,b,c] = [a|T] % Succeeds with `T` bound to `[b,c]` because the first element
% `a` is the same in both cases.
[1,2,3] = [H|T] % Succeeds with `H` bound to 1, and `T` bound to `[2,3]`
% since `[1,2,3]` is equivalent to `[1|[2,3]]` (they are two
% different syntaxes representing the same term)
Just an aside: Prolog list syntax
We're writing lists using a form that's familiar from other languages. So [] is an empty list, and [1,2,3] is a list of the 3 elements 1, 2, and 3. You can also have lists inside of lists, or any terms in a list for that matter. This, for example, is a valid list of 3 elements: [a, [1,foo(a)], bar(x,Y,[])]. The first element is a, the second is a list of two elements, [1, foo(a)], and the third element is bar(x,Y,[]). In Prolog, you can also write a list in a form that describes the first of one or more elements and a tail. For example [H|T] is a list whose first element is H and the rest of the list is T (itself a list). A list of at least two elements could be written as [H|T] and you'd know that T has at least one element. Or you could write it as [H1,H2|T] and explicitly indicate the first two elements and understand that T would be a list of zero or more arguments. The first elements are individual elements of the list, and the tail is a list representing the rest of the list. The following forms all represent the list [a,b,c,d,e]:
[a,b,c,d,e]
[a|[b,c,d,e]]
[a,b|[c,d,e]]
[a,b,c|[d,e]]
[a,b,c,d|[e]]
[a,b,c,d,e|[]]
If you had a list, L, and wanted prolog to ensure that L had at least two arguments, you could unify L with an anonymous list of 2 elements: L = [_,_|_]. This will only succeed if L is a list of at least two elements.
Another aside: canonical form
Prolog, though, has what it calls a canonical form for terms which is its fundamental representation of a given term. You can see the canonical form of a term by calling write_canonical(Term):
| ?- write_canonical([a,b,c]).
'.'(a,'.'(b,'.'(c,[])))
yes
So that's interesting, what on earth is that? It doesn't look like a list at all! It's actually the canonical form in Prolog of what a list really looks like to Prolog (if you want to think of it that way). The fundamental term form in Prolog is a functor and zero or more arguments. The atom a is a term which could be viewed as a functor a with no arguments. The term foo(1,X) has functor foo and arguments 1 and X. The list [a,b,c] written that way is just a convenient syntax for programmers that make it easy to read. A list is actually formed by the functor '.' and two arguments: the head and the tail. So the list [H|T] in general is '.'(H,T) and the empty list [] is just itself, an atom representing the empty list. When Prolog unifies (or attempts to unify) two lists, it's really looking at a list as '.'(H, T) so it matches the '.' functor, then attempts to match arguments. In the case of multiple elements, it's a recursive match since T is itself a list.
Expressions in Prolog such as X + 3 are also a syntactic convenience for the canonical form, '+'(X, 3).
Back to our story
As we were saying, when you query output([a,b,c,d,e])., Prolog tries to unify this with heads of predicate clauses or facts that you have already asserted. Here's what you have asserted:
output([]).
output([c|R]):- output(R), !, nl.
output([X|R]) :- output(R), write(X).
Starting from the top, Prolog attempts this unification:
output([a,b,c,d,e]) = output([])
This fails since there are no variables to change the terms to make them match. It fails because the list [a,b,c,d,e] and the empty list [] cannot match.
On to the next clause:
output([a,b,c,d,e]) = output([c|R])
This can only succeed if the unification [a,b,c,d,e] = [c|R] can succeed with some binding of R. You can look at this as [a|[b,c,d,e,]] = [c|R]. Clearly, for this unification to succeed, the first element of each list must match. But a and c don't match, so this fails.
On to the next one:
output([a,b,c,d,e]) = output([X|R])
Prolog attempts then to unify [a,b,c,d,e] with [X|R], or [a|[b,c,d,e]] with [X|R]... and this succeeds since X and R are variables and they can be bound as X = a and R = [b,c,d,e]. Now the body of the clause can be executed:
output([b,c,d,e]), write(a).
Before we can get to the write(a), the call output([b,c,d,e]) must execute first and succeed. Following the same logic above, the the first and second clauses of the output/1 predicate do not match. But the 3rd clause matches again with [b,c,d,e] = [X|R] resulting in X = b and R = [c,d,e]. Now the body of this clause is executed again (and you must remember we're now one level deep in a recursive call... the above call to output([b,c,d,e]) is pending awaiting the result):
output([c,d,e]), write(b).
Now it gets more interesting. The first clause of output/1 still doesn't match since [c,d,e] = [] fails. But the second clause now does match since [c,d,e] = [c|R] succeeds with the binding R = [d,e]. So that body is executed:
output([d,e]), !, nl.
Now we need to chase down the call to output([d,e]) (we're now another level deep in recursion remember!). This one fails to match the first two clauses but matches the 3rd clause, by [d,e] = [X|R] with bindings X = d and R = [e].
I could keep going but I'm getting tired of typing and I do have a real job I work at and am running out of time. You should get the idea hear and start working through this logic yourself. The big hint moving forward is that when you finally get to output([]) in a recursive call an you match the first clause, you will start "unwinding" the recursive calls (which you need to keep track of if you're doing this by hand) and the write(X) calls will start to be executed as well as the !, nl portion of the second clause in the case where c was matched as the first element.
Have fun...
The main problem with your reasoning is that c is not a variable but an atom. It cannot be unified with any other value.
So with your example input, for the first 2 calls it will not execute output([c|R]) (since a nor b can be unified with c), but it goes on to output([X|R]) instead. Only for the third call, when the head is c, the former clause is called. After this it will call the latter clause another 2 times for d and e, and then it hits the base case.
From that point on we can easily see the output: if first writes 'e', then 'd', then a new line (for the time we matched c), ad then b and a. Finally you get true as output, indicating that the predicate call succeeded.
Also note that due to the cut we only get a single output. If the cut wasn't there, we would also get edcba, since the c case would also be able to match the last clause.

how to assign one list to a variable in prolog?

I want to append([],C,C) where C is a list containing some elements . Is it possible? I will append some list in C containing elements append (Found,C,C) if other condition is true.
And also i want to store final value in C to a variable D . How can I do that?
I want to append([],C,C) where C is a list containing some elements. Is it possible?
append([],C,C) is always true. An empty list combined with anything is that anything. Look what Prolog says when you attempt it:
?- append([],C,C).
true.
This true without any bindings tells you that Prolog established the proof but no new bindings were created as a result. This code would have the same result:
meaningless(_, _, _).
?- meaningless(everybody, X, Squant).
true.
This suggests your desire is misplaced. append([], C, C) does not do what you think it does.
I will append some list in C containing elements append (Found,C,C) if other condition is true. And also i want to store final value in C to a variable D. How can I do that?
Thinking in terms of "storing" and other operations implying mutable state is a sure sign that you are not understanding Prolog. In Prolog, you establish bindings (or assert facts into the dynamic store, which is a tar pit for beginners). Something similar could be achieved in a Prolog fashion by doing something like this:
frob(cat, List, Result) :- append([cat], List, Result).
frob(dog, List, List).
This predicate frob/3 has two in-parameters: an atom and a list. If the atom is cat then it will append [cat] to the beginning of the list. The threading you see going between the arguments in the head of the clause and their use in the body of the clause is how Prolog manages state. Basically, all state in Prolog is either in the call stack or in the dynamic store.
To give an example in Python, consider these two ways of implementing factorial:
def fac(n):
result = 1
while n > 1:
result = result * n
n = n - 1
This version has a variable, result, which is a kind of state. We mutate the state repeatedly in a loop to achieve the calculation. While the factorial function may be defined as fac(n) = n * fac(n-1), this implementation does not have fac(n-1) hiding in the code anywhere explicitly.
A recursive method would be:
def fac(n):
if n < 1:
return 1
else:
return n * fac(n-1)
There's no explicit state here, so how does the calculation work? The state is implicit, it's being carried on the stack. Procedural programmers tend to raise a skeptical eyebrow at recursion, but in Prolog, there is no such thing as an assignable so the first method cannot be used.
Back to frob/3, the condition is implicit on the first argument. The behavior is different in the body because in the first body, the third argument will be bound to the third argument of the append/3 call, which will unify with the list of the atom cat appended to the second argument List. In the second body, nothing special will happen and the third argument will be bound to the same value as the second argument. So if you were to call frob(Animal, List, Result), Result will be bound with cat at the front or not based on what Animal is.
Do not get mixed up and think that Prolog is just treating the last argument as a return value! If that were true, this would certainly not work like so:
?- frob(X, Y, [whale]).
X = dog,
Y = [whale].
What appears to have happened here is that Prolog could tell that because the list did not start with cat it was able to infer that X was dog. Good Prolog programmers aspire to maintain that illusion in their APIs, but all that really happened here is that Prolog entered the first rule, which expanded to append([cat], X, [whale]) and then unification failed because Prolog could not come up with an X which, having had [cat] prepended to it, would generate [whale]. As a result, it went to the second rule, which unifies X with dog and the second two arguments with each other. Hence Y = [whale].
I hope this helps!

how to split a sentence in swi-prolog

I am trying my hands on SWI-Prolog in win xp. I am trying to understand how to split a sentence in Prolog into separate atoms.
Ex : Say I have a sentence like this :
"this is a string"
Is there any way to get individual words to get stored in a variable?
like :
X = this
Y = is
....
and so forth.
Can anyone please explain how this works?
Thanks.
I would use atomic_list_concat/3. See
http://www.swi-prolog.org/pldoc/man?predicate=atomic_list_concat%2F3
Normally it is meant to insert a separator but because of Prolog's bidirectionality of unification, it can also be used to split a string given the separator:
atomic_list_concat(L,' ', 'This is a string').
L = ['This',is,a,string]
Of course once the split is done you can play with the elements of the list L.
I like the answer of 'pat fats', but you have to convert your string to atom before:
..., atom_codes(Atom, String), atomic_list_concat(L, ' ', Atom), ...
If you need to work directly with strings, I have this code in my 'arsenal':
%% split input on Sep
%
% minimal implementation
%
splitter(Sep, [Chunk|R]) -->
string(Chunk),
( Sep -> !, splitter(Sep, R)
; [], {R = []}
).
being a DCG, must be called in this way:
?- phrase(splitter(" ", L), "this is a string"), maplist(atom_codes, As, L).
L = [[116, 104, 105, 115], [105, 115], [97], [115, 116, 114, 105, 110|...]],
As = [this, is, a, string] .
edit: more explanation
I forgot to explain how that works: DCG are well explained by #larsman, in this other answer. I cite him
-->, which actually adds two hidden arguments to it. The first of these is a list to be parsed by the grammar rule; the second is "what's left" after the parse. c(F,X,[]) calls c on the list X to obtain a result F, expecting [] to be left, i.e. the parser should consume the entire list X.
Here I have 2 arguments, the first it's the separator, the second the list being built. The builtin string//1 come from SWI-Prolog library(http/dcg_basics). It's a very handy building block, that match literally anything on backtracking. Here it's 'eating' each char before the separator or the end-of-string. Having done that, we can recurse...
?-split("this is a string"," ", Out).
Out=["this","is","a"," string"]

Resources