2012-02-19 14 views
10

Czy ktoś może pomóc w znalezieniu błędu w tym regulaminie?Konkatenacja list w Prologu

concat([], List, List). 
concat([Head|[]], List, [Head|List]). 
concat([Head|Tail], List, Concat) :- concat(Tail, List, C), concat(Head, C, Concat). 

Próbując złączyć 2 list kończy się niepowodzeniem:

| ?- concat([1,2], [4,7,0], What). 

no 

Odpowiedz

14

Aby rozwiązać swój kod, tak, jak ma to, po prostu trzeba przekształcić Head w [Head] w swojej ostatniej rozmowy do concat/3 w ostatniej klauzuli . Problem polegał na tym, że wywołałeś swój predykat z Head tylko jako pierwszy argument, który nie jest listą.

Mimo, oto kilka uwag:

  • [Head|[]] jest równoważna [Head]
  • swoim algorytmie ma słabe złożoności, n! Wierzę.
  • bez włożonej cięcia po drugiej klauzuli wygenerować nieskończone punkty wybór na skutek połączenia swojej trzeciej klauzuli z listy o długości 1 (to stąd nazywa swoją drugą klauzulę, która następnie jest prowadzony za pośrednictwem trzeciej klauzuli, itp .. . nieskończona pętla).

Oto wersja SWI-PL jest, aby schować cię do dobrej prolog rekursji:

append([], List, List). 
append([Head|Tail], List, [Head|Rest]) :- 
    append(Tail, List, Rest). 

można znaleźć inne środki na ostatnich postów tutaj lub w Learn Prolog Now! tutorialu jeśli chcesz dowiedzieć się, jak korzystać z rekurencji prawidłowo.

+0

Dzięki za pomoc. Jeszcze jedno pytanie: czy można zobaczyć, jak prolog interpretuje program? na przykład ślad stosu może pomóc w dostrzeżeniu problemu. – damluar

+3

yup, wpisz "trace". Wejdziesz w tryb śledzenia. Aby go opuścić, wpisz 'notrace'. Będziesz w trybie debugowania. Aby wyjść z trybu debugowania, wpisz 'nodebug', a wrócisz do normalnego trybu! – m09

+0

Używam gnu prolog, to działa dla mnie. dzięki! – damluar

4

Można to zrobić za pomocą Append.

concatenate(List1, List2, Result):- 
    append(List1, List2, Result). 

Mam nadzieję, że to pomoże.

0

Oto powiązanie pomiędzy dwa wykazy zasadą:

concat([],L2,L2). concat([Head|Tail],L2,[Head|L3]) :- concat(Tail,L2,L3).