Ir para o conteúdo
  • Revista PROGRAMAR: Já está disponível a edição #60 da revista programar. Faz já o download aqui!

Ziwdon

[Resolvido] Validação de regras

Mensagens Recomendadas

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)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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.

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros 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)

Partilhar esta mensagem


Ligação para a mensagem
Partilhar noutros sites

Crie uma conta ou ligue-se para comentar

Só membros podem comentar

Criar nova conta

Registe para ter uma conta na nossa comunidade. É fácil!

Registar nova conta

Entra

Já tem conta? Inicie sessão aqui.

Entrar Agora

×

Aviso Sobre Cookies

Ao usar este site você aceita os nossos Termos de Uso e Política de Privacidade. Este site usa cookies para disponibilizar funcionalidades personalizadas. Para mais informações visite esta página.