Jump to content
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Sign in to follow this  
Ziwdon

[Resolvido] Validação de regras

Recommended Posts

Ziwdon

Boas,

Agradecia se me pudessem esclarecer relativamente ao seguinte:

No Prolog, quando definimos duas rules, com o mesmo functor, se a primeira rule for validada, isto é, se devolver true, então a segunda regra já não será testada correcto? Ou seja,

rule(N):-N is 1, write('1'), nl.
rule(N):-N is 2, write('2'), nl.

No caso descrito em cima, a segunda rule nunca será testada certo? O output obtido será então:

1

Assumindo que o que acabei de escrever é de facto verdade, então suponha-se a seguinte situação:

menu:-repeat,
      write('Quer ou não quer?'),nl,
      write('1 - Sim'),nl,
      write('2 - Não'),nl,
      write('0 - Sair'),nl,
      read(Opcao),
      rule(Opcao),
      Opcao==0, !, abort.

rule(1):-1 is 1, write('1'), !.
rule(2):-2 is 2, write('2'), !.
rule(0):-!.
rule(_):-write('Opção inválida!'), nl.

O output obtido para o exemplo apresentado em cima, tendo como input o caractere '1', é o seguinte:

1

A minha questão é porque é que é necessário incluir um cut no fim de cada uma das rules?

Caso os cuts sejam removidos, obtém-se:

1
Opção inválida!

Uma vez que a primeira rule é validada, porque é que a rule rule(_) é sempre testada?

É uma questão muito básica, mas que neste momento me está a criar alguma confusão.

Obrigado.

Carlos.


"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)

Share this post


Link to post
Share on other sites
Baderous

Boas,

Agradecia se me pudessem esclarecer relativamente ao seguinte:

No Prolog, quando definimos duas rules, com o mesmo functor, se a primeira rule for validada, isto é, se devolver true, então a segunda regra já não será testada correcto? Ou seja,

rule(N):-N is 1, write('1'), nl.
rule(N):-N is 2, write('2'), nl.

No caso descrito em cima, a segunda rule nunca será testada certo?

Errado. Quando o interpretador é invocado, ele gera uma árvore com as diversas ramificações que pode seguir para esse predicado, e começa a percorrer a 1ª ramificação. Quando chega ao fim, volta atrás e percorre as que faltam, ou seja, faz backtracking.

Assumindo que o que acabei de escrever é de facto verdade, então suponha-se a seguinte situação:

menu:-repeat,
      write('Quer ou não quer?'),nl,
      write('1 - Sim'),nl,
      write('2 - Não'),nl,
      write('0 - Sair'),nl,
      read(Opcao),
      rule(Opcao),
      Opcao==0, !, abort.

rule(1):-1 is 1, write('1'), !.
rule(2):-2 is 2, write('2'), !.
rule(0):-!.
rule(_):-write('Opção inválida!'), nl.

O output obtido para o exemplo apresentado em cima, tendo como input o caractere '1', é o seguinte:

1

A minha questão é porque é que é necessário incluir um cut no fim de cada uma das rules?

Caso os cuts sejam removidos, obtém-se:

1
Opção inválida!

Uma vez que a primeira rule é validada, porque é que a rule rule(_) é sempre testada?

É uma questão muito básica, mas que neste momento me está a criar alguma confusão.

Obrigado.

Carlos.

Tem a ver com o que expliquei. Os cuts servem para cortar os ramos da árvore de prova que se sabe que irão falhar (impede o backtracking), de modo que quando ele volta atrás para ver se há mais ramos a percorrer, não encontra mais ramos porque foram cortados pelos cuts.

Share this post


Link to post
Share on other sites
Ziwdon

Obrigado pela resposta Baderous.

Hmm...então ele percorre sempre as rules todas? No primeiro exemplo, ele chega a testar a segunda rule?


"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)

Share this post


Link to post
Share on other sites
Ziwdon

Sim, eu testei isso agora mesmo, fazendo rule(1).

Estranho. É que eu também estou a fazer debug, no SWI-Prolog, e ele não chega a testar a segunda rule.

E mais...estou a testar o seguinte:

rule(1):-1 is 1,  write('1'), nl.
rule(2):-2 is 2, write('2'), nl.
rule(_):-3 is 3, write('3'), nl.

E o output que obtenho, fazendo rule(1) é:

1

e não como seria de esperar,

1
3

Ou seja, é mais ou menos a mesma situação que no menu, sem os cuts, mas ele não entra na última rule.

Cada vez percebo menos disto  :wallbash: .


"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)

Share this post


Link to post
Share on other sites
Baderous

Eu também testei no SWI-PROLOG (com o exemplo do 1º post), e o 1º resultado para rule(1). é:

1

true

Mas depois metes ponto e vírgula ; para ele indicar as respostas seguintes, e ele devolve false.

Share this post


Link to post
Share on other sites
Ziwdon

Eu também testei no SWI-PROLOG (com o exemplo do 1º post), e o 1º resultado para rule(1). é:

Mas depois metes ponto e vírgula ; para ele indicar as respostas seguintes, e ele devolve false.

Sim tens razão. Acho que já entendi o processo.

Quer ele devolva false, quer ele devolva true, ele vai sempre testar todas as regras e todas as opções possíveis...certo?

Edit: Acho que finalmente percebi como funciona. Ele apenas testa a segunda rule no caso da primeira falhar. Caso contrário, se conseguir efectuar a primeira rule, acaba aí. A não ser claro, que nós próprios forcemos o compilador a testar as outras rules, através do uso do ;.

Obrigado pelo tempo Baderous.


"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)

Share this post


Link to post
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
Sign in to follow this  

×

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.