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.
Related
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])
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.
Am writing a program that includes a definition for the predicate 'word_replacements/2'. This predicate should be true if the two arguments are lists, and the second list is the same as the first but with all elements that are the single letter 'a' replaced by the letter 'e', and with all elements that are the single letter 'e' replaced by the letter 'a'. Your answer should reproduce the following example input/output:
?- word_replacements([e, a, s, i, l, y],Word_replacements).
Word_replacements = [a, e, s, i, l, y];
false.
?- word_replacements(Word, [a,e,s,i,l,y).
Word = [e, a, s, i, l, y];
false.
This is what I have tried but it just gives me false.
word_replacements([],[]).
word_replacements([H|T], Word_replacements):-
word_replacements(H,Replace_A),
word_replacements(T,Replace_E),
Append(Replaced,[T],Word_replacements).
A first thing to understand about Prolog is that you cannot reassign variables because of unification. Once you assign a value to a variable, it will never change again. This has implications for your example, since it seems you are trying to replace variables holding specific characters.
Of course there are various ways to solve this, but since you stated that you are new to prolog, I'll try to provide a (unfinished) simple way of writing this:
Firstly, we'll evaluate your code:
word_replacements([],[]).
word_replacements([H|T], Word_replacements):-
(1) word_replacements(H,Replace_A),
(2) word_replacements(T,Replace_E),
(3) append(Replaced,[T],Word_replacements).
What you wrote is the following:
(1) : recursive call to word_replacements, however with H as first argument, since H is not a list, but an element, this will never pattern match and thus execution will fail here.
(2) : recursive call to word_replacements, this time with T, the tail of the list, and this indeed is a list as well, so that would be correct. However, as second argument, you specify a new uninstantiated variable 'Replace_E). Prolog does not know where this variable comes from and will thus give you the warning 'Singleton variable'. When you make recursive calls, you want to end up with a result afterwards, this means you will have to pass a known variable between recursive calls, instead of a new singleton variable.
(3) : here you try to append another new variable 'Replaced' with the tail of the letters enclosed in square brackets. This would wrap the tail, which is already in a list, into another list and you would end up with something like [['l','y']], which is not what you want.
Okay, we'll now start by breaking down the problem into the following possible states (this used to help me alot when I was new to Prolog):
The specified list of letters is empty
The current letter being read is an 'a'
The current letter being read is an 'e'
The current letter being read is some other letter than 'a' or 'e'
We now try to translate this into prolog code:
% Empty list
word_replacements([],[]).
% If H is an 'e', we want to add an 'a' to our result
word_replacements([H|T],[a|R]) :-
...
word_replacements(T,R).
% If H is an 'a', we want to add an 'e' to our result
word_replacements([H|T],[e|R]) :-
...
word_replacements(T,R).
% If H is anything other than an 'a' or 'e', we want to keep that letter
word_replacements([H|T],[H|R]) :-
...
word_replacements(T,R).
As you can see, we now wrote a structured model in which it is easy to specify different behaviour for different situations.
All that's left to do now, is for you to specify the conditions for each situation.
Good luck!
I am trying to use Prolog's append and length predicates for the first time in order to split a list, and I believe it requires a recursive solution. I am new to Prolog, and would like some help with this starter problem! :)
Here is the expected code output:
?- splits([1,2,3],S).
S = [1]/[2, 3] ;
S = [1, 2]/[3] ;
false.
It takes a list and splits it, but it does so by creating a structure with the functor /, this is what confuses me so far... I know that I need to use append for this, but how would one do so?
Here is my code so far:
splits([H | T], S) :-
length(T, len), len > 0,
It will run until the tail of the list is empty, and then stop, but I can't quite figure out how to add in the append function or make it recursive... Could someone give me a tip? :)
I would say that you are almost at a working implementation with your remark that append/3 can be used for splitting lists. This is indeed what append/3 in the instantiation (-,-,+) does.
The only added requirement that seems to occur in your question is to exclude cases in which either of the splits is empty. This can be achieved by checking for inequivalence between terms using \==/2.
This results in the following code:
splits(List, X/Y):-
append(X, Y, List),
X \== [],
Y \== [].
PS: Notice that your use of len in your code snippet is wrong, since len is not a Prolog variable but an atom. Handing an atom to the second argument of length/2 produces a type error, and an arithmetic error in len > 0 (provided that len is not defined as a function). (Both observations relate to SWI-Prolog.)
Hope this helps!
Here is a recursive approach:
splits([A,B|T], [A]/[B|T]).
splits([A|T], [A|R]/S) :-
splits(T, R/S).
The first clause provides the base case of splitting a list with at least 2 elements ([A,B|T]) into [A]/[B|T] (it just splits out the first element).
The second clause says that [A|R]/S is the split of [A|T] if R/S is the split of T. So it will "generate" the other solutions recursing down to the base case. If the first list has only two elements, the base case will be successful, and backtrack to the recursive case will fail on the first try (which is what you want - no more solutions to that case) because the recursive case only succeeds when the first list has 3 or more elements (A plus the two enforced on T in the recursive query).
| ?- splits([1], S).
no
| ?- splits([1,2], S).
S = [1]/[2] ? ;
no
| ?- splits([1,2,3], S).
S = [1]/[2,3] ? ;
S = [1,2]/[3] ? ;
no
...
I know that we can concat atoms using atom_concat(Para1,Para1,Final)., Is there any function available in Prolog which can perform the reverse operation mean it takes input as an atom and provides two atom in which one is the last character of the atom and second is remaining one. eg.
?- rev_atom_concat(likes,Para1,Para2).
Para1 = like, Para2 = s
I am not sure that is this really possible or not..?
You may use sub_atom for this. sub_atom extracts part of an atom. The syntax is:
sub_atom(+Atom, ?Before, ?Len, ?After, ?Sub)
Atom is the initial atom; Sub the sub-atom. Extraction works this way:
<************************ Atom ************************>
<***** Prefix *****><***** Sub *****><**** Suffix *****>
<-- before chars --><-- len chars --><-- after chars -->
For example, to extract the last character:
?- sub_atom(likes, _, 1, 0, S).
S = s.
For exemple, to extract all the characters but the last one:
?- sub_atom(likes, 0, _, 1, S).
S = like.