Q:

Manipular lista e somar itens da lista em Prolog

Sou iniciante em Prolog e tenho dúvida na manipulação de lista e a soma de seus itens.
Tenho um predicado historico(RA,[i1,i2,i3,...,in]) onde ra é o Registro Acadêmico de um aluno e cada i é um item, com a forma item(CM,SM,AN,NT,FQ), sendo que CM é o código da matéria cursada, SM é o semestre, AN é o ano, NT a nota, e FQ a frequência.
Além disso, o predicado curriculo(Codigocurso,[i1,i2,...,in]) onde cada i é o código de uma matéria, nos mostra as matérias de cada curso.
O predicado materia(Codigomateria,Nomemateria,Creditosmateria) nos mostra quantos créditos tem cada matéria no seu terceiro parâmetro.
Suponha que tenho os seguintes fatos:
historico(08080808,[item(1,1,2008,3.0,0.77),item(1,2,2008,6.5,0.90),item(5,1,2009,8.0,0.80)]).

materia(1,algoritmos_e_programacao_para_computadores_1,4).

materia(2,paradigmas_de_programacao,4).

materia(3,programacao_orientada_a_objetos,4).

curriculo(1,[1,2,3]).

Quero fazer uma função que verifique qual a porcentagem de créditos já cumpridos por um certo aluno.
Para isso, terei a função porcentagemcreditos(RA,Codigocurso,Porcentagemjacumprida).
Preciso primeiramente somar os créditos de todas as matérias do curso do aluno (considerando as matérias presentes no currículo), mas não sei como somar os itens de uma lista para que eu tenha o total de créditos de um curso.
Além disso, a função porcentagemcreditos deve desconsiderar as matérias que forem extracurriculares, ou seja, se ele cursou alguma matéria que não está no currículo do seu curso.
Para contextualizar, tenho as seguintes regras que já criei, mas acho que não serão necessárias, apenas as regras que já mencionei:
curso(CODIGOCURSO,NOMECURSO).

materia(CODIGOMATERIA,NOMEMATERIA,CREDITOSMATERIA).

curriculo(CODIGOCURSO,[CODIGOMATERIA1,CODIGOMATERIA2,...,CODIGOMATERIAn).

aluno(RA,NOME).

cursa(RA,CODIGOCURSO).

historico(RA,[ITEM1,ITEM2,...,ITEMn).  (como mostrei anteriormente).

pertence_curso(M,C):-curriculo(C,Lista),member(M,Lista).

A:

Para fazer aritmética em Prolog se usa o predicado is/2: o lado direito precisa conter uma expressão concreta (i.e. não pode ter variáveis livres), que será avaliada e o resultado unificado com o lado esquerdo.
Sendo assim, uma função [ingênua] para somar itens de uma lista seria assim:
somar([], 0).
somar([elemento(_,_,N,_,_)|R], Total) :-
    somar(R, Subtotal),
    Total is N + Subtotal.

Onde elemento(A,B,C,D,E) é somente um exemplo, e você está interessado em somar os Cs.
A função acima pode ser reescrita de modo a possuir recursão de cauda (e assim ser mais eficiente, consumindo uma quantidade constante de memória):
somar(Lista,Resultado) :-
    somar(Lista, 0, Resultado). % zero é o valor inicial

somar([], Acc, Acc). % Se a lista acabou, retorne o que foi acumulado até então
somar([elemento(_,_,N,_,_)|R], Acc, Resultado) :-
    NovoAcc is Acc + N,
    somar(R, NovoAcc, Resultado).

(A variável Acc é um "acumulador", que vai recebendo os valores somados até então e - quando a recursão acabar - corresponderá ao resultado final. Ela pode ser vista como um "subtotal", mas o nome "acumulador" é bastante usado em Prolog, de modo que é bom você se familiarizar com ele)
Para fazer então a função porcentagemCreditos que você quer, serão necessárias as seguintes coisas:

Obter todas as matérias do curso e somar seus créditos. Seu curriculo/2 te dá a lista de códigos das matérias do curso, de modo que você pode adaptar a função somar acima pra pegar cada código de matéria, consultar seu total de créditos em materia/3 e usar esse valor na soma;
Obter todas as matérias cursadas pelo aluno e somar seus créditos. De novo, você pode adaptar o somar acima para iterar sobre os itens do histórico do aluno, exceto que nesse caso você vai "saltar" as matérias que não fazem parte do curso:
...
somar_historico(Curso, [item(M,_,_,N,F)|R], Acc, Resultado) :-
    pertence_curso(M, Curso),
    passou(N,F), % Exemplo: o aluno só ganha créditos se passou, certo?
    !,
    materia(M,_,Creditos),
    NAcc is Acc + Creditos,
    somar_historico(Curso, R, NAcc, Resultado).
% Se a matéria não fazia parte do curso, ou o aluno não passou, salta esse item
somar_historico(Curso, [_|R], Acc, Resultado) :-
    somar_historico(Curso, R, Acc, Resultado).

Dividir um pelo outro. De novo, usando is e o operador de divisão / (ou multiplicação por 100 via * e divisão inteira via //, dependendo de como você quer o resultado).

