2017-02-03 8 views
0

Я новичок в Prolog, пытаясь суммировать только первые элементы каждого списка.Пролог суммирования первых индексов списков

takeFirst([[1,2,3],[4,5,6],[7,8,9]],R). --> R=1+4+7=12 

Он продолжает выдавать ложные данные, и я не понимаю, чего мне здесь не хватает.

takeFirst([HF|_],[],HF):-!. 
takeFirst([H|L1],R):- H=[_|_], L1=[_|_],!,takeFirst(H,L1,NN), R is NN. 
takeFirst([HF|_],[K|L2],HF):- takeFirst(K,L2,NN), HF is HF+NN. 

Кто-нибудь видит, что здесь не так?

+0

Что должно быть сделано в случае, если есть пустой список в данном списке? –

+1

вы не можете * добавить * элементы в Prolog; Prolog - это * декларативный * язык, что означает, что переменные не могут измениться, когда они назначены. –

+0

Я ошибочно сказал «добавление их», но я menat вернул список первого элемента каждого списка. в этом случае возвращая '[1,4,7]', как я сказал. Я в основном спрашиваю, могу ли я заменить «Rb - Ra + HH» на «Rb = [Ra, HH]», потому что у меня были некоторые проблемы с этим раньше. – mooly

ответ

1

Ну, ваш код довольно хаотичен: сначала вы определяете takeFirst/3 (вероятно, это должен быть базовый корпус?). Затем вы определяете два рекурсивных случая, но вы как-то передаете глава список в рекурсивном вызове и т. Д.

На самом деле проблема легко решить. Сначала лучше перенаправить takeFirst/2 к takeFirst/3` с аккумулятором:

takeFirst(L,R) :- 
    takeFirst(L,0,R). 

Далее мы рассмотрим базовый случай: мы достигли конца списка:

takeFirst([],R,R). 

В этом случае мы достигли конца, и поэтому значение аккумулятора, которое мы передаем, которое отслеживает сумму до сих пор, возвращается в результате.

В рекурсивном случае, нам дан список [H|T], и мы заинтересованы в главе головыHH так [[HH|_]|T]. В этом случае мы добавим HH к аккумулятору и рекурсивный вызов с T:

takeFirst([[HH|_]|T],Ra,R) :- 
    Rb is Ra+HH, 
    takeFirst(T,Rb,R). 

Так положить его вместе мы получаем:

takeFirst(L,R) :- 
    takeFirst(L,0,R). 

takeFirst([],R,R). 
takeFirst([[HH|_]|T],Ra,R) :- 
    Rb is Ra+HH, 
    takeFirst(T,Rb,R). 

Что-то, что было не очень понятно, в вашем вопросе является то, что должно если в вашем списке есть пустой список, например [[1,2,3],[],[7,8,9]]. Вышеупомянутый предикат не будет выполнен: он ожидает, что все списки имеют хотя бы один элемент. В случае, если вы просто хотите, чтобы игнорировать эти списки, вы можете изменить свой код в:

takeFirst2(L,R) :- 
    takeFirst2(L,0,R). 

takeFirst2([],R,R). 
takeFirst2([[]|T],Ra,R) :- 
    takeFirst2(T,Ra,R). 
takeFirst2([[HH|_]|T],Ra,R) :- 
    Rb is Ra+HH, 
    takeFirst2(T,Rb,R). 

Таким образом, мы добавим случай, когда список следует шаблону [[]|T], в этом случае мы просто выполнить рекурсивный вызов с хвостом T ,

Исходя из приведенных выше предикатов, построение списка глав не трудно, а также:

heads([],[]) 
heads([[HH|_]|TA],[HH|TB]) :- 
    heads(TA,TB).