I am writing a predicate that separates consecutive elements(all negative or positive) into different groups
like
same([1,2,3,-1,-3,-2,4,5,6],X).
would output [[1,2,3],[-1,-3,-2],[4,5,6]]
and my code is below(only positive part):
same([],[]).
same([H|T],[[X,Y,H]|Tail]):-
X >= 0,
H >= 0,
same(T,[[X,Y]|Tail]).
Error message:ERROR: Arguments are not sufficiently instantiated
ERROR: In:
ERROR: [9] _4652>=0
ERROR: [8] sign_runs([2,2|...],[_4696,_4702|...]) at /Users/filepath:40
ERROR: [7] <user>
Could somebody help? Thanks in advance.
When you call same([1,2,3,-1,-3,-2,4,5,6],X). the second clause is called.
H is instancied with 1, T with [2,3,-1,-3,-2,4,5,6].
So when X >= 0 is called, X is unknown.
[EDIT]
You must start the work from the end of the list, so we need three things, what do we do when we reach the end, what we do after, and how we reach the end of the list !
When there is only one element, it's easy :
same([X], [[X]]).
Now when we have got the start it's easysimple, we work with this configuration :
same([H|T], [[X|T1]|Tail]).
From same([X], [[X]]), T is instancied with [], idem for T1 and Tail.
Now we just have to check the product H*X
If it's greater than 0 we put H in the head of [X|T1] e.g. [H,X|T1], if not we create a new list
[[H],[X|T1]|Tail].
The last thing if to reach the end of the list. Recusion if our friend
same([H|T], Tail) :-
same(T, Tail1),
...
Now we can write the whole code :
same([X],[[X]]).
same([H|T], Tail):-
same(T, [[X| T1]|Tail1]),
/* Bad answer for [1,2,0,-5]
( H*X >= 0
-> Tail = [[H, X | T1] | Tail1]
; Tail = [[H], [X|T1] | Tail1]).
*/
( H >= 0
-> (X >= 0
-> Tail = [[H, X | T1] | Tail1]
; Tail = [[H], [X|T1] | Tail1])
; (X < 0
-> Tail = [[H, X | T1] | Tail1]
; Tail = [[H], [X|T1] | Tail1])).
And we get :
?- same([1,2,3,-1,-3,-2,4,5,6],X).
X = [[1, 2, 3], [-1, -3, -2], [4, 5, 6]] ;