Prolog (arguments not instantiated)

2019-09-01 19:01发布

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.

标签: list prolog
1条回答
三岁会撩人
2楼-- · 2019-09-01 19:47

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]] ;
查看更多
登录 后发表回答