To find maximum and minimum of a list in prolog - list

domains
list = integer*//shows error in swish saying "syntax error operator
expected"
Max = integer
predicates
maximum_no(list,integer)
clauses
maximum_no([],Max):-
write("Maximum No in List is:: ",Max),nl.
maximum_no([H|T],Max):-
H>Max,
N = H,
maximum_no(T,N).
maximum_no(L,Max):-
maximum_no(L,Max).
Can someone please tell me how do I solve this error ? I do find the code is correct but it still says an error?
I also have to write the code to find the minimum number of a list!!

The following alone works in order to find the max of a list :
% the maximum of a list of one element is this element
maximum_no([X],X).
% the maximum of a list is either the head or the maximum of the tail
% depending on if the head is lower than the max of the tail.
maximum_no([H|T],Max):-
maximum_no(T,Max),
H #< Max.
maximum_no([Max|T],Max):-
maximum_no(T,M),
M #< Max.
Then, finding the min of a list shouldn't be too complicated.

This should work. For the minimum just make the proper changes.
maximum_no([H|T],Max):-
maximum_no(T,MX),
Max is max(H,MX).

Related

How to check for membership in a list in CLINGO?

Having a background in Prolog, I'm struggling to convert this DLV (which has builtin predicates to handle lists similarly to Prolog) program into CLINGO.
path(X,Y,[X|[Y]]) :- rel(X,Y).
path(X,Y,[X|T]) :- rel(X,Z), path(Z,Y,T), not #member(X,T).
rel(X,Y) :- edge(X,Y).
rel(X,Y) :- edge(Y,X).
edge(a,b).
edge(a,c).
edge(b,a).
edge(b,c).
edge(e,c).
So far I managed to achieve this:
path(X,Y,cons(X,cons(Y,empty))) :- edge(X,Y).
path(X,Y,cons(X,L)) :- edge(X,Z), path(Z,Y,L), not member(X,path(Z,Y,L)).
member(X,path(X,T,cons(X,Y))) :- path(X,T,cons(X,Y)).
member(X,path(S,X,cons(S,L))) :- path(S,X,cons(S,L)).
member(X,path(S,T,cons(S,cons(Z,L)))) :- member(X,path(Z,T,cons(Z,L))).
% same edges
but I get the error unsafe variables in in file - at line 7 and column 1-72 and I don't fully understand why. I was wondering if anyone could help.
You never defined what S could be.
Add edge(S,Z) to the rule body on line 7 to get rid of that error. Or if you want to define a vertex predicate you could use vertex(S) as well.
So I fixed your code with the cons-lists. This approach is unusual because lists are not a key feature in asp like they are in prolog. Ok, here is my solution (works for directed graphs):
edge(a,b).
edge(a,c).
edge(b,c).
edge(c,a).
edge(c,d).
edge(d,b).
node(X) :- edge(X,_). % get nodes
node(X) :- edge(_,X). % get nodes
num(N):- {node(X)} == N. % count nodes
step(1..N) :- num(N). % mark possible steps
path(X,Y,2,cons(X,cons(Y,empty))) :- edge(X,Y).
path(A,C,NN+1,cons(A,L)) :- edge(A,B), path(B,C,NN,L), step(NN+1).
member(X,path(X,Y,N,cons(X,L))) :- path(X,Y,N,cons(X,L)).
member(Y,path(X,Y,N,cons(X,L))) :- path(X,Y,N,cons(X,L)).
member(M,path(S,T,NN+1,cons(S,cons(Z,L)))) :- member(M,path(Z,T,NN,cons(Z,L))), path(S,T,NN+1,cons(S,cons(Z,L))).
track(Y,Z,N,L):- {member(X,path(Y,Z,N,L)):node(X)} == N, path(Y,Z,N,L).
#show track/4.
At first you need to know all the of vertices to calculate their number. Also I introduced the predicate step to validate a depth for the path. path also has a depth-counter now as third argument. All possible paths are stored within path/4, cycles are allowed. The member/2 predicate is generated to show all the member vertices within a path/4. In a last step all path's are forwarded to the predicate track/4 if and only if the number of distinct member vertices equals the path length. Since duplicates will not be counted this condition makes sure that only paths without cycles are forwarded. Please note that all of the above steps are forced. There is exactly one answer set for every graph.
So let's have a look at a more ASP like solution. Normally you would ask a specific question ('path from a to b with length n') instead of a generic one ('all possible paths from all nodes to all nodes with every possible length'). The following code needs to have a start node (start/1) and an end node (end/1). The program forces a (random) order by assigning exactly one index number to each vertex within the predicate order/2. The order predicate is copied to the path predicate as long as the index is not larger than the index of the end node (path(S,N):- order(S,N), maxZ(Z), S<=Z.). The only constrains is that within the order of path every 2 neighboring vertices are connected with an edge. The constraint line is read as It can not ne the case that there is a node S1 on position N within a path and a node S2 on position N+1 within a path and there is no edge from S1 to S2.
edge(a,b).
edge(a,c).
edge(b,c).
edge(c,a).
edge(c,d).
edge(d,b).
start(a).
end(d).
node(X) :- edge(X,_). % get nodes
node(X) :- edge(_,X). % get nodes
num(N):- {node(X)} == N. % count nodes
step(1..N) :- num(N). % mark possible steps
order(1,A):- start(A). % start has index 1
maxZ(Z):- end(E), order(Z,E), step(Z). % end has index maxZ
{order(S,N):node(N)} == 1 :- step(S). % exactly one assignment per step
{order(S,N):step(S)} == 1 :- node(N). % exactly one assignment per node
path(S,N):- order(S,N), maxZ(Z), S<=Z. % copy order when index is not largter than end node index
:- path(N, S1), path(N+1, S2), not edge(S1,S2). % successing indices are connected through edges
#show path/2.

Finding the longest run of positive integers in OCaml

Trying an OCaml question of iterating through the list and finding the longest run of positive or negative integers. My thinking so far is you have to use List.fold_left and somehow +1 to the accumulator each time the next sign is the same as the current sign. However, I'm a bit stuck on how to save that value. Any help would be appreciated.
I suspect you're being downvoted because this is the kind of basic question that's probably best answered by looking at an introduction to OCaml or functional programming in general.
The essential idea of folds in general and List.fold_left in particular is to maintain some state while traversing a collection (or a list in particular). When you say you want to "save" a value, the natural answer is that the value would be part of the state that you maintain while traversing the list.
The template for calling List.fold_left looks like this:
let final_state =
List.fold_left update_function initial_state list
The update function takes the current state and the next element of the list, and returns the value of the next state. So it looks like this:
let update_function old_state list_element =
let new_state =
(* compute based on old state and element *)
in
new_state
So the explicit answer to your question is that your update function (the function that you "fold" over the list) would save a value by returning it as part of the new state.
Here's some code that returns the largest non-negative integer that it sees in a list:
let largest_int list =
let update largest_so_far element =
max largest_so_far element
in
List.fold_left update 0 list
This code "saves" the largest int seen so far by returning it as the value of the update function. (Note that it returns a value of 0 for an empty list.)
Ah dang im also up all night doing OCaml LOL!!!
here's my shot at it ... one way is to sort the list and then find the first positive or first negative depending on how you sort ... checkout sort function from https://caml.inria.fr/pub/docs/manual-ocaml/libref/List.html ... then it's easy to get the size.
Let's say you don't want to use this built in library ... This code should be close to working (If my editor/debugger worked with OCaml I'd further test but I think this is close to good)
let mostPositives(l: int list) : int list=
let counter = ref 0 in
let maxSize = ref 0 in
for i = 0 to List.length(l) -1 do
if (List.nth l i) >= 0 then
counter := !counter + 1
else
counter := 1;
maxSize := (max !counter !maxSize );
done;

Accessing previous elements of python list comprehension

I have the following list:
a = [1,(landa/mu)]
I want to add elements to this list using previous elements:
a = a + [[f(i)*a[n-i] for i in range(1,n)] for n in range(2,K)]
in which f is a function and landa, mu and K are parameters. However, it is giving me the following error:
list index out of range
Could you please tell me how can I solve this problem? I can simply write it in a for loop but I want it to be in a list comprehension format to be done fast since K sometimes become a large number.

Finding the max value of a list of tuples, (applying max to the second value of the tuple)

So I have a list of tuples which I created from zipping two lists like this:
zipped =list(zip(neighbors, cv_scores))
max(zipped) produces
(49, 0.63941769316909292) where 49 is the max value.
However, I'm interesting in finding the max value among the latter value of the tuple (the .63941).
How can I do that?
The problem is that Python compares tuples lexicographically so it orders on the first item and only if these are equivalent, it compares the second and so on.
You can however use the key= in the max(..) function, to compare on the second element:
max(zipped,key=lambda x:x[1])
Note 1: Note that you do not have to construct a list(..) if you are only interested in the maximum value. You can use
max(zip(neighbors,cv_scores),key=lambda x:x[1]).
Note 2: Finding the max(..) runs in O(n) (linear time) whereas sorting a list runs in O(n log n).
max(zipped)[1]
#returns second element of the tuple
This should solve your problem in case you want to sort your data
and find the maximum you can use itemgetter
from operator import itemgetter
zipped.sort(key=itemgetter(1), reverse = True)
print(zipped[0][1]) #for maximum

How do I count the number of elements in a list?

I need to write a small Prolog program to count the number of occurrence of each element in a list.
numberOfRepetition(input, result)
For example:
numberOfRepetition([a,b,a,d,c,a,b], X)
can be satisfied with X=[a/3,b/2,d/1,c/1] because a occurs three times, b occurs 2 times and c and d one time.
I don't want to give you the answer, so I gonna help you with it:
% Find the occurrences of given element in list
%
% occurrences([a,b,c,a],a,X).
% -> X = 2.
occurrences([],_,0).
occurrences([X|Y],X,N):- occurrences(Y,X,W),N is W + 1.
occurrences([X|Y],Z,N):- occurrences(Y,Z,N),X\=Z.
Depending on your effort and feedback, I can help you to get your answer.
Check out my answer to the related question "How to count number of element occurrences in a list in Prolog"!
In that answer I present the predicate list_counts/2, which should fot your needs.
Sample use:
:- list_counts([a,b,a,d,c,a,b],Ys).
Ys = [a-3, b-2, d-1, c-1].
Note that that this predicate uses a slightly different representation for key-value pairs expressing multiplicity: principal functor (-)/2 instead of (/)/2.
If possible, switch to the representation using (-)/2 for better interoperability with standard library predicates (like keysort/2).
If you wish to find element with max occurrences:
occurrences([],_,0).
occurrences([X|Y],X,N):- occurrences(Y,X,W),N is W + 1.
occurrences([X|Y],Z,N):- occurrences(Y,Z,N),X\=Z.
**make_list(Max):-
findall((Num,Elem),occurrences([d,d,d,a,a,b,c,d,e],Elem,Num),L),
sort(L,Sorted),
last(Sorted,(_,Max)).**