Jump to content

Apontamentos de Prolog


Rui Carlos

Recommended Posts

Deixo aqui algumas notas que podem ajudar a aprender esta linguagem:

Texto/tutorial sobre ProLog (da autoria do Professor F. Mário Martins)

https://web.archive.org/web/20070707221440/http://sim.di.uminho.pt/disciplinas/ppiii/0405/PTT_PPIII_v2.doc

Como interpretador podemos usar o SWI-Prolog ou SICStus Prolog, disponíveis para Windows, Linux e Mac OS X.

Editores como o Vim (e certamente muitos outros) possuem syntax highlighting para o Prolog, se bem que normalmente é preciso indicar que estamos a usar o ProLog (pois os ficheiros .pl são normalmente associados ao Perl). No Vim podemos fazê-lo através do comando :set syntax=prolog.

Link to comment
Share on other sites

  • 3 months later...
  • 3 years later...

Rui Carlos sei que já lá vão uns anitos mas nem imaginas o jeito que isto me vai dar.

Foi-me dado agora um projecto de Prolog e tenho 3 semanas para o fazer, sem qualquer introdução à linguagem em si ou como funciona minimamente (infelizmente é assim que as coisas funcionam aqui...é ao desenrasca-te).

O facto de teres disponibilizado esta aplicação em Prolog mais um PDF...é a minha salvação! 😛 Ainda por cima com relatório e o código todo comentadinho e tudo. Yes! xD

Vais-me poupar anos (bem anos não porque só tenho 3 semanas...mas prai 2 semanas) de desespero e bater com a cabeça nas paredes. É que ainda por cima é difícil encontrar-se bom material na net.

Muito obrigado 🙂

Cumps.

"Rejoice not against me, O mine enemy: when I fall, I shall arise; when I sit in darkness, the LORD shall be a light unto me." - Micah 7:8 (KJV)

Link to comment
Share on other sites

Não sei se fiz bem, mas estou com umas dúvidas em prolog e resolvi utilizar esta thread para as tirar, em vez de criar uma nova!

Estou a estudar esta linguagem, e empanquei na resolução de um exercício, o divisório, que recebe uma lista de vários números e executa sucessivas divisões, p.e.:

[10,5,4] -> 10/5 = 2

2/4 = 0.5

O resultado seria 0.5

Eu fiz a seguinte função:

operatorio(/, [], 1).
operatorio(/,[H|T],R) :- Res is R/H, operatorio(/, T, Res).

Sei que isto está mal, pois na primeira iteração a variável R não irá conter nenhum valor, mas não arranjo melhor maneira de resolver isto... Alguém me pode ajudar?

Link to comment
Share on other sites

Em 17/04/2010 às 23:54, Rui Carlos disse:

Ja há alguns anos que não mexo em ProLog, mas deve ser algo como:

operatorio(/,[X],X).
operatorio(/,[H1|H2|T],R) :- H is H1/H2, operatorio(/,[Res|T],R).

Retiras dois elementos, operas, e colocas o resultado de novo na lista (operatorio([10,5,4])=operatorio([2,4])).

Acho que na 2ª cláusula querias dizer Res em vez de H.

Link to comment
Share on other sites

Antes de mais, obrigado pela ajuda!

Em 17/04/2010 às 23:54, Rui Carlos disse:
operatorio(/,[X],X).
operatorio(/,[H1|H2|T],R) :- H is H1/H2, operatorio(/,[Res|T],R).

Essa função precisaria de um outro caso de paragem, para quando a lista tivesse apenas 2 elementos. Ou estou enganado? Ainda assim, não me está a funcionar isso! E o Sicstus diz que tens um erro de sintaxe, aqui:

[H1|H2|T]

Se puser assim não se queixa:

[H1,H2|T]

A função a que cheguei foi esta:

operatorio(/,[X],X).
operatorio(/,[X,Y],R) :- R is X/Y.
operatorio(/, [H1,H2|T], R) :- R is H1/H2, operatorio(/,[R|T], R).

Se testar com uma lista que tenha mais do que 3 elementos, a resposta do Sicstus é sempre NO... Alguém sabe porquê?

Link to comment
Share on other sites

Vê a alteração que eu fiz ao meu post anterior. Não podes usar o R em vez do H, pois o R já estava a ser usado. E não, não deves precisar de prever o caso em que a lista tem dois elementos.

Já percebi o que estavas a fazer. A primeira vez que olhei para o teu código, pensei que o R não estava a ser utilizado, mas agora percebi que ao chegar ao caso de paragem, o valor calculado (que vai ser o único da lista) vai passar para o R. Muito obrigado!

Link to comment
Share on other sites

Boas!

Estou a tentar fazer um predicado que apague a primeira ocorrência de um dado elemento de uma lista, mas não estou a conseguir implementa-lo!

apagar(_, [], []).
apagar(H, [H|T], T).
apagar(Y, [_|T], L) :- apagar(Y, T, [H|L]).

Penso que isto falhe por causa do L inicialmente ser uma variável. Consigo ver que tenho isto mal, mas não sei como corrigir... Alguém me pode ajudar?

Link to comment
Share on other sites

No terceiro caso seria mais apagar(Y, [H|T], [H|L]) :- apagar(Y, T,L)., ou seja, calculas o resultado de aplicar a função à cauda, e depois adicionas-lhe a cabeça.

Eventualmente precisarás de garantir que o Y é diferente do H (como o Baderous fez).

Funcionou, mas estou a olhar para a função e não faço a mínima de como isto funciona... Eu estava a tentar reconstruir a lista no 3º parâmetro, o que não faz sentido nenhum (apercebi-me agora) devido ao 2º caso de paragem.

Não percebo como o 3º parâmetro da query:

apagar(20, [1,2,2,20,3,2,1], X).

Unifica com o 3º parâmetro do predicado apagar:

apagar(Y, [H|T], [H|L]) :- apagar(Y, T, L).

Admitindo que o Prolog infere que a variável X seja o que for preciso para satisfazer o predicado, não percebo o que sucede no 3º parâmetro aquando das chamadas recursivas. Por exemplo:

apagar(20, [1,20,3], X).

Esta query vai unificar com a 3ª cláusula do predicado, e a chamada recursiva será:

apagar(20, [20,3], (......)).

Não consigo mesmo perceber o que vai ali nas (......)

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.