prologeclipse-clp

prolog max_min_eval/2 solution issue


I want to create a predicate max_min_eval/2 or max_min_eval(List,Result) which read a list like this [1,min,2,max,4,max,3] -> (((1 min 2) max 4) max 3) in eclipse prolog and put the Result into a varialble. How can I do this?

This is my code:

%% seperate_lists/3
%% seperate_lists(List,Lets,Nums)

seperate_lists([], [], []) . 


seperate_lists([X|Xs] , [X|Lets] , Nums) :- 
  not(number(X)),
  !, 
  seperate_lists(Xs,Lets,Nums). 


seperate_lists( [X|Xs] , Lets, [X|Nums] ) :- 
  number(X),  
  !, 
  seperate_lists(Xs,Lets,Nums). 


seperate_lists([_|Xs], Lets, Nums) :-
  seperate_lists(Xs,Lets,Nums). 



%% max_min_eval/2
%% max_min_eval(List,Result)
max_min_eval_aux(_,[Result],Result).

max_min_eval_aux(Lets, Nums, Result) :-
    [LH|LT] = Lets,
    [NH1,NH2|NT] = Nums,
    (
        ('max' = LH, max(NH1,NH2,Result), append([Result],NT,NewNums), NewLets = LT, max_min_eval_aux(NewLets,NewNums,Result));
        ('min' = LH, min(NH1,NH2,Result), append([Result],NT,NewNums), NewLets = LT, max_min_eval_aux(NewLets,NewNums,Result))
    ).


max_min_eval(List,Result) :-
    seperate_lists(List,Lets,Nums),
    max_min_eval_aux(Lets,Nums,Result).

The problem is that it doesn't work for ?- max_min_eval([1,max,10,min,2],Result), only works for 3 element list like this ?- max_min_eval([1,max,4],Result) or ?- max_min_eval([2,min,5],Result)


Solution

  • You may greedily evaluate the expression:

    max_min_eval([First|Tail], Res):-
      max_min_eval(Tail, First, Res).
      
    max_min_eval([],Res, Res).
    max_min_eval([Op, R|Tail], L, Res):-
      max_min_eval_op(Op, L, R, L1),
      max_min_eval(Tail, L1, Res).
    
    max_min_eval_op(max, L, R, Res):-
      max(L, R, Res).
    max_min_eval_op(min, L, R, Res):-
      min(L, R, Res).
    

    Add these procedures if your prolog processor does not have max/3 and min/3:

    max(A,B,M):- M is max(A,B).
    min(A,B,M):- M is min(A,B).
    

    Sample run:

    ?- max_min_eval([1,min,2,max,4,max,3], R).
    R = 4.