Hephaestus
Hephaestus

Reputation: 19

Why am I getting Type error: `[]' expected, found `[21,3,4,5,6,7,8]' (a list) ("x" must hold one character) with maplist/3 prolog?

I am new to Prolog. I want a predicate that takes a list, process it with maplist/3 creating a corresponding list with zeros in place of numbers less than mean and 1 for number above the mean. I then want a second predicate to sum the 1's to find out how many numbers are above the mean. This second predicate then returns this number which corresponds to total numbers above the mean.

I know the code below works fine:

numAtOrAboveMean(Mean, Num, Val) :- Num > Mean -> Val  is 1; Val is 0.
maplist(numAtOrAboveMean(Mean), [], List), sumlist(List, Below). 

When I modified it to this, I get a type erros that expected [] but found a list. The comments correspond to how I think the predicate behavior is.

nGMean(Mean, Num, Val) :- Num > Mean -> Val  is 1; Val is 0.%sorts list
nGMean([], _ , []). %takes a list, a constant, relates to a list
nGMean(L, Mean, List) : - maplist(nGMean(Mean), L, List). %maplist call sort

Then to sum I will use a second predicate. Something like this:

sumtotal(L,V) :- mean(L, M), M2 is M, nGMean(L, M2, List), sum(List, V).

Which is not working probably mostly because nGMean is throwing an error. nGMean full error is shown below:

nGmean predicate Error

So my question is, why am I getting that type error on the nGMean predicate?

Edit -As requested in comments below is the entire thing. As I explained that is the only part because I am testing it separately. Thank you for answers. Next time I will post complete code.Or make clear that I just want to trouble shoot one predicate.

Maplist for numAtOrAboveMean

Full Pic of code on Editor

Upvotes: 2

Views: 4863

Answers (1)

Tomas By
Tomas By

Reputation: 1394

You should post complete code that can just be copied and run. In what you have posted, mean/2 and sum/2 are not defined.

(Addition:) the reason for the error seems to be that you are comparing a value and a list (2<[2,3|...]). The reason this happens is because your first clause for nGMean/3 has Mean as first parameter, whereas the other clauses has the list, i.e. the list becomes Mean which is used in the comparison (Num > Mean). I'm not sure how > becomes <.

Also, calling maplist/3 on an empty list does not make sense.

A recursive predicate should have two clauses. A recursive clause that (typically) does something with the head of the list and then calls recursively on the tail, and a base case (empty list).

nGMean([Num|Nums],Mean,[Val|List]) :-
  ( Num > Mean ->
    Val = 1
  ; Val = 0 ),
  nGMean(Nums,Mean,List).
nGMean([],_,[]).

With this definition I get the same output as your first two lines above, so I believe this is what you wanted.

(Earlier addition: you only need to use is when the right-hand side contains mathematical calculations. To just set a value, = is fine.)

Upvotes: 3

Related Questions