So I am using prolog and i Have a funcntion like this:
ratingList(X):-goalKeeperRating(X,A),centreForwardRating(X,B),secondStrikerRating(X,C),centreDefenseRating(X,D),fullBackRating(X,E),centerMidfieldRating(X,F),attackingMidfieldRating(X,G),defendingMidfieldRating(X,H),
Y=[[goalKeeper,A],[centerForward,B],[secondStriker,C],[centerDefense,D],[fullBack,E],[centerMidfield,F],[attackingMidfieldRating,G],[defendingMidfieldRating,H]],
maxlist(Y,N),N=[L,M],write('Best Position ' + L + ' with rating ' +M).
Basically the first line finds numbers and put it in the second element, then we put numbers in a list (Y). Everything in Y is a list of length 2 with a soccer position name plus the number we got. MaxList just finds the maxinum number. it looks like this
maxlist([A],A).
maxlist([A,B|C],D):- A=[_,X],E=[_,Y],D=[_,Z],maxlist([B|C],E),max(X,Y,Z),.
max(A,B,A):-A>=B.
max(A,B,B):-A<B.
However, whenever I try to print the word it always results in printing the address. Is there anyway I can fix this?
You are constructing D without giving it's first element any value. The max function must work with the whole element not just the second element of the list. In your own style
maxlist([A], A).
maxlist([A, B | As], M) :-
maxlist([B | As], M1), max(A, M1, M).
max(A, B, A) :- A = [_, X], B = [_, Y], X >= Y.
max(A, B, B) :- A = [_, X], B = [_, Y], X < Y.
A iterative way to find the maximum of the list
maxlist([X | Xs], Max) :- maxlist(Xs, X, Max).
maxlist([], A, A).
maxlist([B | Bs], A, C) :-
A = [_, X], B = [_, Y],
(X > Y -> T = A ; T = B),
maxlist(Bs, T, C).
Related
I just can't seem to get the correct output - I am supposed to get -
?- dfs([a], X).
X = [a, f, i] ;
false.
But I get -
?- dfs([a], X).
X = [a|f] ;
% Representation of a tree
% choose initial state a
arc(a, b).
arc(a, f).
arc(b, c).
arc(b, d).
arc(b, e).
arc(f, g).
arc(f, i).
arc(i, j).
arc(i, k).
% the goal
goal(i).
dfs([Node|_], [Node|X]) :-
goal(X).
dfs([Node|_], [Node|X]) :-
expands([Node|_], NewNode),
append([Node|_], NewNode, appendedN),
dfs(appendedN, X).
% expands(+Path, ?NewNode).
% -- Path: is a list of nodes of the form Path=[Node|Nodes], where
% Node is the node we want to expand and Nodes is a list
% of remaining nodes already expanded and containing the root.
% -- NewNode: is a constant representing the node we want to go to,
% as there is an link to it from where we are currently.
%
expands([Node|_], NewNode):-
arc(Node, NewNode).
Your program matches the first clause, dfs([Node|_], [Node|X]), and nothing else, producing X = [a|i] .
Here's a working version.
% Representation of a tree
% choose initial state a
arc(a, b).
arc(a, f).
arc(b, c).
arc(b, d).
arc(b, e).
arc(f, g).
arc(f, i).
arc(i, j).
arc(i, k).
% the goal
goal(i).
% You can expand a starting symbol S to a list L if G is your goal, S expands
% to G in list L1, and you append the two lists.
dfs([S], L) :-
goal(G),
expands(S, G, L1),
append([S], L1, L).
% X expands to Y in list [Y] if there's a direct arc from X to Y (base case).
expands(X, Y, [Y]) :-
arc(X, Y).
% X expands to Z in list [Y|L] if there's a direct arc from X to Y and Y
% expands to Z in list L (recursive case).
expands(X, Z, [Y|L]) :-
arc(X, Y),
expands(Y, Z, L).
In this version, expands() produces all of the lists that start with a:
?- expands(a, X, L).
X = b,
L = [b] ;
X = f,
L = [f] ;
X = c,
L = [b, c] ;
X = d,
L = [b, d] ;
X = e,
L = [b, e] ;
X = g,
L = [f, g] ;
X = i,
L = [f, i] ;
X = j,
L = [f, i, j] ;
X = k,
L = [f, i, k] ;
false.
Then dfs() confirms that the goal i has been reached and adds the start symbol a to the head of the list:
?- dfs([a], X).
X = [a, f, i] ;
false.
If I run solved([[x, o, o], [o, o, o], [o, o, o]]) it should output true as there is only x and if I run solved([[x, o, o], [o, o, o], [o, o, x]]) it should output false as there is more than 1 x. However, running it outputs true all the time as it infers a value for C.
:- use_module(library(clpfd)).
rotate_clock(Xss, Zss) :-
transpose(Xss, Yss),
maplist(reverse, Yss, Zss).
rotate_anti(Xss, Zss) :-
maplist(reverse, Xss, Yss),
transpose(Yss, Zss).
linjmp([x, x, o | T], [o, o, x | T]).
linjmp([o, x, x | T], [x, o, o | T]).
linjmp([H|T1], [H|T2]) :- linjmp(T1,T2).
horizjmp([A|T],[B|T]) :- linjmp(A,B).
horizjmp([H|T1],[H|T2]) :- horizjmp(T1,T2).
jump(B,A) :- horizjmp(B,A).
jump(B,A) :- rotate_clock(B,BR), horizjmp(BR,BRJ), rotate_anti(BRJ, A).
num_x(A, C) :- count(A, x, C).
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([_|T],X,Z):- count(T,X,Z).
sum_list([], 0).
sum_list([H|T], Sum) :-
sum_list(T, Rest),
Sum is H + Rest.
solved(A) :-
maplist(num_x, A, B),
sum_list(B, C),
C == 1.
Instead of trying to change the behavior of a language (which might be possible, but is of course a challenge), it might be better to investigate why eventually Prolog finds a C with C == 1. If we evaluate the maplist(num_x, A, B), ourselves, we see:
?- maplist(num_x, [[x, o, o], [o, o, o], [o, o, x]], B).
B = [1, 0, 1] ;
B = [1, 0, 0] ;
B = [0, 0, 1] ;
B = [0, 0, 0].
So it appears that the num_x/2 predicate, can generate multiple results, for the same list: for a list with one x, it first generates 1, and then 0.
This is confirmed if we do some tests with count/3:
?- count([x, o, o], x, C).
C = 1 ;
C = 0.
?- count([x, x, o], x, C).
C = 2 ;
C = 1 ;
C = 1 ;
C = 0.
So it appears that count/3 each time has a backtracking point where it can decide to count a given x, or not.
Indeed, if we take a look at the count/3 predicate, we see:
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([_|T],X,Z):- count(T,X,Z).
So here for a non-empty list, there are two ways clauses: one where the head is equal to X, the element we want to count, in which case Y is 1+Z, but the last clause says that, regardless what the value of the head is, Prolog will not count that element. Prolog performs backtracking, and thus will eventually pick both clauses.
We can add a dif/2 to add a constraint that the head and X should be differrent, like:
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([H|T],X,Z):- dif(H, X), count(T,X,Z).
So now if an X appears in the list, we will count that element.
Very, VERY new to Prolog here. My function needs to compare two lists of equal length by taking the larger number into a new list (e.g. larger([3, 12, 5], [6, 3, 11], X) returns X = [6, 12, 11].) This is what I have, but it is not getting me what I need:
larger([],[],[]).
larger([H|T],[E|A],X):- H > E, larger([T],[A],[H|X]).
larger([H|T],[E|A],X):- H < E, larger([T],[A],[E|X]).
Any help is much appreciated.
The other answer is OK, this is a slightly different approach.
Two clauses should be enough:
larger([], [], []).
larger([X|Xs], [Y|Ys], [Z|Zs]) :-
/* Z is the larger number from (X, Y) */
larger(Xs, Ys, Zs).
How you do the part in the comments depends on your exact problem statement and maybe the implementation. At least SWI-Prolog and GNU-Prolog both have an arithmetic function max() that you can use like this in the above:
larger([], [], []).
larger([X|Xs], [Y|Ys], [Z|Zs]) :-
Z is max(X, Y),
larger(Xs, Ys, Zs).
This is arguably nicer than the solution with three clauses because it won't leave behind unnecessary choice points. Like the other solution, it will work fine as long as the two lists have numbers in them.
This would be identical to using a maplist, for example like this:
larger(Xs, Ys, Zs) :-
maplist(max_number, Xs, Ys, Zs).
max_number(X, Y, Z) :- Z is max(X, Y).
You're not far.
Try with
larger([], [], []).
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
larger([H | T], [E | A], [E | X]) :-
H =< E,
larger(T, A, X).
If I'm not wrong, there are three errors in your code.
(1) you have to translate the bigger head value (H or E) in the third argument of larger/3, not in the recursive call
% ------- H added here ---v
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
% not here ----^
(2) T and A, the tails in [H|T] and [E|A], are lists, so you have to pass they recursively as T and A, not as [T] and [A]
larger([H | T], [E | A], [H | X]) :-
H > E,
larger(T, A, X).
% not larger([T], [A], X)
(3) if you have the cases H > E and H < E, your code fail when H is equal to E; one solution is H > E and H =< E; the secon case cover H equal to E.
I found a 3 year old question that helps me count the number of occurrences of variables within a list. The question had the answer below. The code works. But I can't understand how, can someone help me make sense of this?
Here is the answer with the code I found, writing in quotation marks is part of the answer:
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).
'However note that the second argument X is supposed to be instantiated. So e.g. count([2,23,3,45,23,44,-20],23,C) will unify C with 2. If you want the count for every element use'
:- use_module(library(lists)).
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z)
countall(List,X,C) :-
sort(List,List1),
member(X,List1),
count(List,X,C).
'Then you get'
?- countall([2,23,3,45,23,44,-20],X,Y).
X = -20,
Y = 1 ;
X = 2,
Y = 1 ;
X = 3,
Y = 1 ;
X = 23,
Y = 2 ;
X = 44,
Y = 1 ;
X = 45,
Y = 1 ;
no
I am very new to Prolog, I only understand one part of this code, and it is this
sort(List,List1),
member(X,List1),
I would appreciate an explanation of this the whole thing, especially how Y is being printed.
About counting, first try to think about the meaning of the code.
list_member_occ([], _, 0). % list is empty, 0 occurrences
list_member_occ([X|Xs], X, N) :- % list has the element at the head
list_member_occ(Xs, X, N0), % count number of elements in the tail
succ(N0, N). % the number of occurrences is the
% next natural number
list_member_occ([Y|Xs], X, N) :-
dif(X, Y), % head and the element are different
list_member_occ(Xs, X, N). % occurrences in the tail of the list
% is the total number
In this code, succ(N0, N) is (arguably) a better way to say "N is the natural number after N0" than N is N0 + 1. One reason is that succ/2 was meant to be used in every direction:
?- succ(2, 3).
true.
?- succ(X, 4).
X = 3.
?- succ(1, X).
X = 2.
... while is/2 should be used with unbound left operand. Take this query
?- list_member_occ([1,1,2,1], X, 3).
... for an example of N being a number instead of a free variable.
Using the predicate:
?- list_member_occ([1,2,1], X, N).
X = 1,
N = 2 ;
X = 2,
N = 1 ;
N = 0,
dif(X, 1),
dif(X, 2),
dif(X, 1).
One interesting property of dif/2, as opposed to \=/2, is that it imposes a constraint on the variable X in the last solution: X cannot, from now on, take any of the values 1, or 2.
For the reason why you get all answers using dif/2, consider:
?- X = Y. % unify X and Y and succeed
X = Y.
?- X \= Y. % succeed if you cannot unify X and Y
false.
?- dif(X, Y). % succeed if X and Y are and will be different
dif(X, Y).
When you use X \= Y, Prolog tries to unify its arguments and fails if the unification succeeds. This means that you only get the solution in which all free variables have been unified to each other, but you miss solutions where free variables are different from each other.
About the Y = ..., when you make a query at the top level, it reports to you all new variable bindings that were made during successful proofs of this query. As the most simple example:
Which numbers are between 3 and 5, both including?
?- between(3, 5, X).
X = 3 ;
X = 4 ;
X = 5.
You don't need, of course, to print out the values of X by hand; just type a semicolon to get the next answer. After the last answer you get a full stop and return to the ?- prompt.
About the sorting: it sorts the whole list, but only shows you the first 9 elements of the sorted list. See this FAQ page from SWI-Prolog. In a nutshell, the easiest is to type ; true after your query, to make sure that there is at least one choice point, and use w and p to switch between showing the whole term and only some of it.
?- string_chars("the quick brown fox jumps over the lazy dog", Cs), sort(Cs, S) ; true.
Cs = [t, h, e, ' ', q, u, i, c, k|...],
S = [' ', a, b, c, d, e, f, g, h|...] [write]
Cs = [t, h, e, ' ', q, u, i, c, k, ' ', b, r, o, w, n, ' ', f, o, x, ' ', j, u, m, p, s, ' ', o, v, e, r, ' ', t, h, e, ' ', l, a, z, y, ' ', d, o, g],
S = [' ', a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z] .
?- string_chars("the quick brown fox jumps over the lazy dog", Cs), sort(Cs, S) ; true.
Cs = [t, h, e, ' ', q, u, i, c, k, ' ', b, r, o, w, n, ' ', f, o, x, ' ', j, u, m, p, s, ' ', o, v, e, r, ' ', t, h, e, ' ', l, a, z, y, ' ', d, o, g],
S = [' ', a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z] [print]
Cs = [t, h, e, ' ', q, u, i, c, k|...],
S = [' ', a, b, c, d, e, f, g, h|...] .
Hope this helps.
Just a little question because I do not understand something on a program I have at one of my finals :
p(A, [A | _]).
p(B, [_, _ | C]) :- p(B, C).
q(D, [_, D | _]).
q(E, [_, _ | F]) :- q(E, F).
r(G, H) :- p(G, H).
r(I, J) :- q(I, J).
The question is to make the Tree of research of that with the purpose : r(X, [a,b,c]).
So actually, two possibilities :
r(G, H) :- p(G, H). (With G = X, and H = [a,b,c]).
r(I, J) :- q(I, J). (With I = X, and J = [a, b, c]).
If we take the 1st one, we have : p(X, [a,b,c]).
So we can use the 1st rule : p(A, [A | _]). (With A = X).
But I don't understand why when I launch the SWI-Prolog, a goes into X ...
Thanks !
Satisfying r(X, [a,b,c]) with the first rule goes into satisfying p(X, [a,b,c]).
Your first rule for p/2, p(A,[A|_]), states that a goal p(X,L) is satisfied when L is a list and its first element unifies with X.
In your case that list is [a,b,c] and X is unified with a.