2016-08-03 21 views
5

Jestem nowy w prologu i próbuję napisać predykat encode(L,L1) który liczy duplikaty elementów w L, na przykład:orzecznik zakodować w prologu

encode([4,4,4,3,3],L). 

L=[3,4,2,3]. 

To co napisałem:

encode(L,L1) :- encode(L,1,L1). 

encode([],_,[]).  
encode([H],N,[N,H]).  
encode([H,H|T],N1,[N,H|T1]) :- M is N1+1, encode([H|T],M,[N,H|T1]).  
encode([H,Y|T],N,[N,H|T1]) :- H\=Y, encode([Y|T],T1). 

Powyższy predykat nie jest odwracalny. Działa tylko wtedy, gdy podano pierwszy parametr.

Jak zapisać kodowanie odwracalne?
Na przykład:

encode(L,[3,4,2,3]).   
L = [4,4,4,3,3]. 
+0

Zamiast "M to N1 + 1" wypróbuj 'M # = N1 + 1'. Upewnij się, że załadowałeś moduł CLP (FD) (': - use_module (library (clpfd)).) A zamiast' \ = 'użyj' \ == '. – lurker

+0

@lurker, Próbowałem powyższych, ale nadal po wprowadzeniu zmian, problem pozostaje: kodowanie (L, [3,4,2,3]) nie daje żadnej odpowiedzi (zgłasza wyjątek "Out of local stack"). – coder

Odpowiedz

4

Myślę, że algorytm posiada redundantne licznik w nim. Nieco uproszczony byłoby:

encoded([], []). 
encoded([X], [1,X]). 
encoded([X,Y|T], [1,X|R]) :- 
    dif(X, Y), 
    encoded([Y|T], R). 
encoded([X,X|T], [N,X|R]) :- 
    N #> 1, 
    N #= N1 + 1, 
    encoded([X|T], [N1,X|R]). 

Uwaga w ostatnim punkcie, musimy upewnić się, że N jest większa niż 1, jak również.

+0

Wielkie dzięki! to się udało!!! – coder

+1

@ koder: zauważ, że nawet "zakodowany (Xs, [2, V])." Daje idealną odpowiedź! – false

+1

@ koder: I nawet 'zakodowany (Xs, [2, V, 2, W]).'! Czy widzisz "dif" w pełnej odpowiedzi? – false