Gramáticas DCG s Linguagem Natural 1. Dada a seguinte gramática s --> a,b. a --> [a] [a], a. b --> [b] []. (a) Como é que ela é traduzida pelo Prolog? s(a,z) :- a(a,b),b(b,z). a(a,z) :- C (A,a,Z) ; C (A,a,B), a(b,z). b(a,z) :- C (A,b,Z) ; A = Z. (b) Como é que se pergunta ao Prolog se a palavra aba é reconhecida pela gramática, como sendo da categoria s??- s([a,b,a],[]) ou?- phrase(s,[a,b,a]). 2. Defina uma gramática DCG que gere a linguagem formada por 0 ou mais a's = a* aaaa --> []. aaaa --> [a],aaaa. 3. Linguagem formada por 0 ou mais b's = (a+b)* ab --> []. ab --> [a],ab. ab --> [b],ab. 4. Estenda a gramática anterior de forma a devolver so o numero de b's ab(0) --> []. ab(n) --> [a],ab(n). ab(n) --> [b],ab(x),{n is X + 1}. 5. Agora queremos obter o numero de a s menos o numero de b s. dif_ab(0) --> []. dif_ab(n) --> [a],dif_ab(x), {N is X - 1}. dif_ab(n) --> [b],dif_ab(x), {N is X + 1}. 6. devolve o numero de a's e de b's aeb(0,0) --> []. aeb(a,b) --> [a],aeb(x,b),{a is X + 1}. aeb(a,b) --> [b],aeb(a,x),{b is X + 1}.
7. Construa uma gramática que seja capaz de gerar as palavras sobre o alfabeto {a,b} que são formadas por duas subpalavras concatenadas iguais. (X= W.W). ww --> ba(w),ba(w). ba([]) --> []. ba([a BA]) --> [a],ba(ba). ba([b BA]) --> [b],ba(ba). 8. Considere a linguagem das expressoes aritmeticas com digitos e variáveis (minúsculas). Os operadores são +, *, - e /. a) Construa a gramática que gera as expressões. exp --> elemento elemento, operador, exp. operador --> [+] [*] [-] [/]. elemento --> digito var. digito --> [1] [2] [3] [4] [5] [6] [7] [8] [9]. var --> [x] [y] [z]. b) adapte o exercicio seguinte de modo a devolver a lista de variaveis sem repeticoes. exp(l) --> elemento(l) elemento(e), op, exp(x),{coloca_se_nao_existe(e,x,l)}. op --> [+] [*] [-] [/]. elemento(n) --> digito(n) var(n). digito([]) --> [1] [2] [3] [4] [5] [6] [7] [8] [9]. var([x]) --> [x]. var([y]) --> [y]. var([z]) --> [z]. % Se o primeiro arg. for uma lista vazia coloca_se_nao_existe([],l,l). coloca_se_nao_existe([x],l,l) :- member(x,l),!. coloca_se_nao_existe([x],l,[x L]). 9. Construa uma DCG que seja capaz de gerar as frases que correspondem aos números em extensão que vão de zero a novecentos e noventa e nove mil novecentos e noventa e nove, ou seja um milhão de frases. Adapte essa gramática de maneira a que seja possível construir o inteiro correspondente à sua descrição. :- use_module(library(lists)). unidades --> [zero]. unidades --> unidades1. unidades1 --> [um]. unidades1 --> unidades2. unidades2 --> [dois]. unidades2 --> [tres].
unidades2 --> [quatro]. unidades2 --> [cinco]. unidades2 --> [seis]. unidades2 --> [sete]. unidades2 --> [oito]. unidades2 --> [nove]. dezenas --> [vinte]. dezenas --> [trinta]. dezenas --> [quarenta]. dezenas --> [cinquenta]. dezenas --> [sessenta]. dezenas --> [setenta]. dezenas --> [oitenta]. dezenas --> [noventa]. dezavinte --> [dez]. dezavinte --> [onze]. dezavinte --> [doze]. dezavinte --> [treze]. dezavinte --> [catorze]. dezavinte --> [quinze]. dezavinte --> [dezasseis]. dezavinte --> [dezassete]. dezavinte --> [dezoito]. dezavinte --> [dezanove]. doisanoventanove --> unidades2 dezavinte dezenas dezenas, [e], unidades1. umanoventanove --> unidades1 dezavinte dezenas dezenas, [e], unidades1. zeroanoventanove --> [zero] umanoventanove. cent200 --> [duzentos]. cent200 --> [trezentos]. cent200 --> [quatrocentos]. cent200 --> [quinhentos]. cent200 --> [seiscentos]. cent200 --> [setecentos]. cent200 --> [oitocentos]. cent200 --> [novecentos]. centenase --> [cento]. centenase --> cent200. centenas --> [cem]. centenas --> cent200. zeroa999 --> zeroanoventanove centenas centenase, [e], umanoventanove. uma999 --> umanoventanove centenas centenase, [e], umanoventanove. doisa999 --> doisanoventanove centenas centenase, [e], umanoventanove. esqmil --> []. esqmil --> doisa999. dirmil --> []. dirmil --> uma999. zeroa999999 --> zeroa999 esqmil, [mil], dirmil.
% Com a geração dos inteiros... unidades(0) --> [zero]. unidades(u) --> unidades1(u). unidades1(1) --> [um]. unidades1(u) --> unidades2(u). unidades2(2) --> [dois]. unidades2(3) --> [tres]. unidades2(4) --> [quatro]. unidades2(5) --> [cinco]. unidades2(6) --> [seis]. unidades2(7) --> [sete]. unidades2(8) --> [oito]. unidades2(9) --> [nove]. dezenas(20) --> [vinte]. dezenas(30) --> [trinta]. dezenas(40) --> [quarenta]. dezenas(50) --> [cinquenta]. dezenas(60) --> [sessenta]. dezenas(70) --> [setenta]. dezenas(80) --> [oitenta]. dezenas(90) --> [noventa]. dezavinte(10) --> [dez]. dezavinte(11) --> [onze]. dezavinte(12) --> [doze]. dezavinte(13) --> [treze]. dezavinte(14) --> [catorze]. dezavinte(15) --> [quinze]. dezavinte(16) --> [dezasseis]. dezavinte(17) --> [dezassete]. dezavinte(18) --> [dezoito]. dezavinte(19) --> [dezanove]. doisanoventanove(n) --> unidades2(n) dezavinte(n) dezenas(n) dezenas(d), [e], unidades1(u),{n is D + U}. umanoventanove(n) --> unidades1(n) dezavinte(n) dezenas(n) dezenas(d), [e], unidades1(u),{n is D + U}. zeroanoventanove(n) --> [zero],{n is 0} umanoventanove(n). cent200(200) --> [duzentos]. cent200(300) --> [trezentos]. cent200(400) --> [quatrocentos]. cent200(500) --> [quinhentos]. cent200(600) --> [seiscentos]. cent200(700) --> [setecentos]. cent200(800) --> [oitocentos]. cent200(900) --> [novecentos]. centenase(100) --> [cento]. centenase(n) --> cent200(n). centenas(100) --> [cem]. centenas(c) --> cent200(c). zeroa999(n) --> zeroanoventanove(n) centenas(n)
centenase(c), [e], umanoventanove(d), {N is C + D}. uma999(n) --> umanoventanove(n) centenas(n) centenase(c), [e], umanoventanove(d),{n is D + C}. doisa999(n) --> unidades2(n) zeroanoventanove(n) centenas(n) centenase(c), [e], umanoventanove(d),{n is C + D}. esqmil(0) --> []. esqmil(n) --> doisa999(n). dirmil(0) --> []. dirmil(n) --> uma999(n). zeroa999999(n) --> zeroa999(n) esqmil(e), [mil], dirmil(d), {N is E * 1000 + D}. Uma query prolog pode ser:?- zeroa999999(n,[novecentos,mil,e,um],[]) N = 900001. 10. Suponhamos que podemos enviar a um braço de robô uma sequência de commandos do tipo: cima: anda uma unidade para cima. baixo: anda uma unidade para baixo. esq: anda uma unidade para a esquerda. dir: anada uma unidade para a direita. Construa uma gramática capaz de gerar qualquer sequência de comandos básicos e que devolve o número de comandos enviados. seq(1) --> comm. seq(n) --> comm, seq(x), {N is X + 1}. Comm --> esq dir cima baixo.