how can I write two predicates that are described below.
1) Define the double(X,Y) predicate, which is true if the list Y contains each of the elements X
repeated twice. Example: double([a,b],[a,a,b,b]) is true.
2) Define the predicate repeat(X,Y,N), which is true if the list Y contains each of the elements X
repeated N times. For example, for the question repeat([a,b],[a,a,a,b,b,b],3), Prolog answers true.
Could you give me the example of those predicates?
If you have repeat/3 you have double/2.
and thus:
multiple(X,N,R) :-
length(R,N),maplist(=(X),R).
repeat(Li,Lo,N) :-
maplist({N}/[Xi,Xo]>>multiple(Xi,N,Xo),Li,Nested),flatten(Nested,Lo).
But it doesn't run backwards due to the flatten/2 I think. Can that be improved?
double([], []).
double([X|Y], [X,X|Z]) :- double(Y,Z).
remove_if_same(_,R,0,R):- !.
remove_if_same(X,[X|Y],N,R) :- Nm1 is N-1,remove_if_same(X,Y,Nm1,R).
repeat([],[],_).
repeat([X|Xr],Y,N) :- remove_if_same(X,Y,N,R), repeat(Xr,R,N).
How double works?
If you've got two empty lists, then that is true, there is nothing to double from the first argument.
Otherwise, you're taking the head from the first list, and 2 head elements from the second list. If all these are the same (so if all are X) you're checking with recursion rest of elements, so accordingly Y and Z. So you'll check once again if lists are empty and so on, and if on any of the steps sth is not possible you return false.
About the repeat predicate, it's quite similar in reasoning.
2 things that I should explain:
The ! mark will make that the command-line interface(like swipl) will not search for other results of the remove_if_same. It would work same if we pass it to the repeat.
remove_if_same statement uses the accumulator (the 4th argument) to return at the end of the search the list without N same elements.
Related
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.
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.
I want to construct a list of list to interleave each other to a single list like: coon([[1,4],[2,5],[3,6]], X) should return X=1,2,3,4,5,6. and there is a condition that each sublist should only have the same length, otherwise, it should fail such as [[q,r,y],[a,e],[c,g,t],X] shouid fail, and coon([A,B,C],[q,w,e,r,t,y]) should only return one solution, that is A=[q,r],B=[w,t],C=[e,y].
my recent approach is.
conns([],[]).
conns([[Head|Tail]|X],[Head|Y]):-
append(X,[Tail],X2),
conns(X2,Y).
conns([[]|T],A):-
conns(T,A).
It gives me multiple solutions when I try coon([A,B,C],[q,w,e,r,t,y]).
I have been trying hours to figure it out but all failed. How should I return the single list to each sub-lists that contain the same length?
Thank you so much!
:- use_module(library(clpfd),[transpose/2]).
connsx(Xss, Xs) :-
transpose(Xss, XssT),
append(XssT, Xs).
The problem you are having is with this predicate clause:
conns([[]|T],A):-
conns(T,A).
This allows solutions more general than you are wanting to define. Specifically, if I understand the problem correctly, the first argument to conns should always be a list whose elements are lists all of equal length. That would mean that if [[]|T] is the first argument and you expect conns([[]|T], A) to succeed, then T should also look like [[]|R] or []. That is, it should be a (possibly empty) list of empty lists.
If you revise the empty list case according to this constraint, your solution will work:
% The case where the first argument consists of non-empty lists
conns([[Head|Tail]|X], [Head|Y]):-
append(X, [Tail], X2),
conns(X2, Y).
% Base case in which first argument is a list of empty lists
conns([], []).
conns([[]|T], []) :-
conns(T, []).
Now when you run the query, you get this:
| ?- conns([[1,4],[2,5],[3,6]], R).
R = [1,2,3,4,5,6] ? ;
no
| ?-
As well as:
| ?- conns([A,B,C], [q,w,e,r,t,y]).
A = [q,r]
B = [w,t]
C = [e,y] ? a
no
| ?-
This solution does leave a choice point, which I'll leave as an exercise to eliminate if you wish.
Can someone please help me in transforming this to match this updated requirement?
Define a predicate strikeDuplicates(X,Y) that succeeds if and only the list Y would
be obtained if one were to remove the second and subsequent occurrences of each element
from list X. (You might read strikeDuplicates (X,Y) as list X without duplicates
is list Y.) The strikeDuplicates/2 predicate need not work well when X is an
unbound variable.
I asked a similar question two days ago asking this:
Define a predicate strike(X,Y,Z) that succeeds if and only if the list Z would be
obtained if one were to remove all occurrences of element X from list Y. The
strike/3 predicate need not work well when Y is an unbound variable.
No one helped me so I had to do it by myself. That answer was this:
strike( _ , [] , [] ) .
strike( X , [X|T] , Z ) :- strike(X,T,Z) .
strike( X , [A|T] , [A|Z] ) :- dif(X,A) , strike(X,T,Z) .
dif(X,A).
A simple solution that doesn't preserve order is:
strike_duplicates([], []).
strike_duplicates([X| Xs], List) :-
( member(X, Xs) ->
strike_duplicates(Xs, List)
; List = [X| Tail],
strike_duplicates(Xs, Tail)
).
To preserve order, you need to keep track of the elements found so far while you traverse the list. A solution would be:
strip_duplicates(List, Set) :-
strip_duplicates(List, [], Set).
strip_duplicates([], _, []).
strip_duplicates([X| Xs], Found, List) :-
( member(X, Found) ->
strip_duplicates(Xs, Found, List)
; List = [X| Tail],
strip_duplicates(Xs, [X| Found], Tail)
).
The predicate member/2 is usually either a built-in predicate or available as a library predicate. Check your Prolog system documentation if necessary.
Well, the easy way would be to use the built-in predicate setof/3, but I suspect that's not what your professor wants.
Think about the problem for a second or two. A clear problem statement is often helpful (and in Prolog is often the solution itself):
To make the source list a set (unique elements) instead of a bag (allows duplication), you'll have to
Iterate over the source list
Track items you've already seen (the 'visited' list)
Add each item to the visited list only if the visited list doesn't already contain it.
Once you've done that you've got the desired result.
Here's a hint: a very common prolog idiom is the use of helper predicates that carry with it an accumulator. Often the helper predicate has the same functor, but a different arity. For example, to sum the values in a list (sum/2) we can use a helper sum/3 that carries an accumulator, seeded with 0:
sum(Xs,N) :- sum(Xs,0,N).
sum([],S,S).
sum([N|Ns],T,S) :-
T1 is T+N,
sum(Ns,T1,S)
.
You'll notice how unfication with the result is deferred until the final value has been computed.
You need to do something like that but using as an accumulator an [empty] list that will be extended with the unique values you discover.
Another hint: the built-in predicate member/2 will check if a term is a member of a list. It's written
member(X,[X|Xs]).
member(X,[_|Xs]) :- member(X,Xs).
So member(2,[1,2,3]) is true whilst member(2,[1,3]) is false.
Conversely, one can use member/2 to successively return each element of a list via backtracking: member(X,[1,2,3]) produces
X = 1 ;
X = 2 ;
X = 3 ;
false
Given those two notions, you should be able to figure out the solution. Come back and show us your code and we can help you. There is one other little gotcha, but I'm sure you'll figure it out.
I want to create a rule in prolog that checks if there's a repeated number in a list.
For example:
for [1,2,3,4] it will return true.
for [1,2,3,3] it will return false because the 3 is repeated
I came up with this rule but it doesn't work
Different([]).
Different([H|T]):-
Member(H,T),
Different(T).
Any ideas?
a compact definition could be
all_diff(L) :- \+ (select(X,L,R), memberchk(X,R)).
i.e. all elements are different if we can't peek one and find it in the rest...
edit
Let's (marginally) improve efficiency: it's useless to check if X is member of the prefix sublist, so:
all_diff(L) :- \+ (append(_,[X|R],L), memberchk(X,R)).
The simplest way to check that all list members are unique is to sort list and check that length of the sorted list is equal of length of the original list.
different(X) :-
sort(X, Sorted),
length(X, OriginalLength),
length(Sorted, SortedLength),
OriginalLength == SortedLength.
Your solution doesn't work because of wrong syntax (facts and predicates should not begin with a capital letter) and a logic error. List is unique if head H is not a member of a tail T of a list and tail T is unique:
different([]).
different([H|T]):-
\+member(H,T),
different(T).
If all numbers in that list are integers, and if your Prolog implementation offers clpfd, there's no need to write new predicates of your own---simply use the predefined predicate all_different/1!
:- use_module(library(clpfd)).
Sample use:
?- all_different([1,2,3,4]).
true.
?- all_different([1,2,3,3]).
false.
Very Simple Answer...
The code:
unique([]).
unique([_,[]]).
unique([H|T]):-not(member(H,T)),unique(T).
Tests:
?-unique([1,2,3,4]).
true.
?-unique([1,2,3,3]).
false.
?-unique([a,b,12,d]).
true
?-unique([a,b,a]).
false
A neat way I came up with is the following:
If all members of a list are different from each other, then if I tell prolog to choose all pairs (I,J) such that I,J are members of the list and also I is equal to J, then for each element in the list it will only be able to find one such pair, which is the element with itself.
Therefore, if we can put all such pairs in a list, then the length of this list should be of the same length of the original list.
Here's my prolog code:
all_diff(L) :-
findall((I,J), (member(I, L), member(J, L), I == J), List),
length(L, SupposedLength),
length(List, CheckThis),
SupposedLength == CheckThis.
The rule provided in the question is very close to a correct answer with minimal library usage. Here's a working version that required only one change, the addition of \+ in the third row:
uniqueList([]).
uniqueList([H|T]):-
\+(member(H,T)),
uniqueList(T).
Explanation of the code for Prolog beginners: The member(H,L) predicate checks if element H is a member of the list L. \+ is Prolog's negation function, so the above code amounts to:
uniqueList([H|T]) returns true if: (H doesn't have a copy in T) and uniqueList(T)
Whereas the code by the original asker didn't work because it amounted to:
uniqueList([H|T]) returns true if: (H has a copy in T) and uniqueList(T)
*I renamed Different() to uniqueList() because it reads better. Convention is to reserve capital letters for variables.
This isn't very efficient, but for each number you can check if it appears again later. Like so:
Different([H|T]):-
CheckSingle(H, [T]),
Different([T]).
Checksingle(_,[]).
Checksingle(Elem, [H, T]):-
Elem != H,
Checksingle(Elem, [T]).