2
votes

I am trying to write a function longer(S1,S2) which should be true if S1 is longer than S2, otherwise false. What I have so far is the following:

longer(A,nil). 
longer(nil,B) :- false.
longer([A,AS],[B,BS]) :- longer(AS,BS).

But for some reason I cannot seem to get it to parse correctly when I provide for instance the input: longer([1,2],[1]). But when I run the above through swi-prolog it return false.

Another example is running the: longer([1],nil) which also return false, even though it should be true by matching with list(cons(A,As)) where As = nil, finally matching the end clause.

What am I missing? Can someone point me in the right direction here, as I cannot see how this is not evaluating to true.

Edit: it should be noted that I am still fairly new to prolog at this point.

Update I have had some misunderstanding in relation to what is common prolog semantic. Including trying to force the program to yield a false value (probably being steered by my understanding of non-declarative language semantics). I have updated my answer with the inputs from @tiffi.

1
what is nil and cons?tiffi
@tiffi nil is the equivalent to the empty list [] in prolog. cons is a prolog operator than represents a binary functor, such that: cons(1,cons(2,cons(3,nil))) is equavalent to 1.2.3.nil or [1,2,3].NewDev90
?- nil=[]. false. ?- cons(1,cons(2,cons(3,nil)))=[1,2,3]. false.tiffi
It is what I have been taught briefly, and also read it several places - so this assumption is based on what is being told to me.NewDev90
@tiffi the documentation I have found online is eg: irisa.fr/prive/ridoux/ICLP91/node7.html among others. But none of these are well documented! So I may just assume their correctness due to lack of experience. This is also my first introduction to declarative programming.NewDev90

1 Answers

2
votes

That is a solution that is pretty close to the thinking behind what you have come up with:

longer([_|_],[]).
longer([_|As], [_|Bs]):- longer(As,Bs).

Your idea with regard to the first clause (before your edit) could be expressed like this:

longer(A,[]):- is_list(A). %is_list/1 is inbuilt

However, that doesn't give you the right result, since the empty list is also a list. Thus you need to make sure that the first argument is a non-empty list.