Advertisement
Guest User

Untitled

a guest
Jun 5th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Racket 18.16 KB | None | 0 0
  1. #lang racket
  2.  
  3. (define (weights n graph) ;retorna todos os custos do nó atual n
  4.    (map third ;pega o terceiro parâmetro de cada parênteses
  5.         (filter (lambda (edge) (equal? n (first edge))) ;procura os parênteses que possuem o primeiro parâmetro igual ao nó passado por parâmetro
  6.                 graph)))
  7.  
  8. (define (kids n graph) ;retorna todos os filhos do nó n passado por parâmetro
  9.    (map second ;pega o terceiro parâmetro de cada parênteses
  10.         (filter (lambda (edge) (equal? n (first edge))) ;procura os parênteses que possuem o primeiro parâmetro igual ao nó passado por parâmetro
  11.                 graph)))
  12.  
  13. (define (next custo lista1 lista2) ;custo é o "x" ou "y" do grafo(lido na fórmula), lista1 será a lista com os todos os custos de um nó(todos os custos de "A" por exemplo, lista2 será a lista com todos filhos de um nó(todos os filhos de "A" por exemplo)
  14.   (cond
  15.     [(or(null? lista1) (null? lista2)) null] ;se uma das listas for null, então não é possível andar no grafo com o custo
  16.     [else(if(equal? custo (first lista1)) (first lista2) (next custo (rest lista1) (rest lista2)))])) ;compara o custo com o primeiro elemento da lista1, caso true retorna o nó de destino usando o custo, senão chama a função next com o restante das listas 1 e 2
  17.  
  18. (define (acharCaminho custo lista) ;procura se o custo passado por parâmetro existe na lista1 que é uma lista de todos os custos de um nó ("A" por exemplo)
  19.   (cond
  20.     [(null? lista) #f] ;se o nó for folha = não há custos para sair daquele nó, logo o custo passado por parâmetro não será encontrado
  21.     [else(if(equal? custo (first lista)) #t (acharCaminho custo (rest lista)))])) ;se achou o custo, retorna true. Senão, percorre a lista.
  22.  
  23.  
  24. (define (proximo destino graph) ;retorna o grafo com o primeiro parênteses possuindo o primeiro parâmetro = destino (Grafo a partir de "B" por exemplo)
  25.   (cond
  26.     [(null? graph) null] ;se o grafo é null, então qualquer grafo seguinte será null
  27.     [else(if(equal? destino (first(map first graph))) graph (proximo destino (rest graph)))])) ;se achou o primeiro elemento = destino, retorna o grafo. Senão, percorre o grafo.
  28.  
  29. (define (constroiLista n elemento lista) ;constroi uma lista com base no elemento e a quantidade de vezes que aquele elemento vai ser inserido na lista
  30.   (if(= 0 n) lista
  31.      (constroiLista (- n 1) elemento (cons elemento lista))
  32.   ))
  33.  
  34. (define (pulaParenteses formula custos parenteses falso) ;caso o grafo seja null, verifica se a formula é incompatível
  35.   (cond[(null? finicio) (set! finicio formula)]) ;guarda a formula antes de ser percorrida
  36.   (cond
  37.     [(null? formula) #t] ;caso o grafo e a formula sejam null, são compatíveis
  38.     [else (if (equal? ")" (first formula)) ; ) indica o fim de uma expressão entre ()
  39.               (if(and (< 0 falso) (equal? "U" (first (rest formula)))) ;se não achou um elemento da formula, indicando que ela é falsa, mas achou uma disjunção
  40.                  (analise (rest (rest formula)) inicio custos parenteses) ;verifica se o segundo lado da disjunção é verdadeiro
  41.                  (if (equal? ")" (first (rest formula))) ;caso ainda haja outra expressão entre (), faz a recursão com o restante da formula
  42.                      (pulaParenteses (rest formula) custos parenteses falso)
  43.                      (if (equal? "U" (first (rest formula))) ;caso ache uma disjunção
  44.                         #t ;primeira parte da disjunção é verdadeira, logo a formula e o grafo são compativeis
  45.                         (display finicio)))) ;se não achou nenhum dos casos acima, então há incompatibilidade da formula inicial guardada em finicio
  46.               (if(or (equal? "?" (first formula)) (equal? "U" (first formula))) ;caso seja uma condicional ou disjunção, a fórmula pode ser compatível com o grafo
  47.                  (analise (rest formula) inicio custos parenteses) ;verifica se é compatível
  48.                  (begin
  49.                    (cond[(= 0 falso)(set! finicio formula)]) ;caso ache qualquer elemento diferente de ? e U, é um elemento inválido e guarda o inicio da formula invalida
  50.                    (pulaParenteses (rest formula) custos parenteses (+ 1 falso)))))])) ;faz a recursão com o restante da formula, sabendo que achou um elemento invalido
  51.  
  52. (define vezes 0) ;quantidade de ( que se anula com a quantidade de )
  53.  
  54. (define inicio null) ;lista auxiliar que guarda o grafo antes de entrar na expressão entre ()
  55.  
  56. (define finicio null) ;lista auxiliar que guarda a formula assim que se começa a verificação de compatibilidade dela
  57.  
  58. (define (analise formula grafo custos parenteses)
  59.   (cond
  60.     [(null? grafo) (if (null? formula) #t (if (null? (rest formula)) (if (equal? ")" (first formula)) #t (display formula)) (if(> vezes 0) (pulaParenteses formula custos parenteses 0) (display formula))))] ;Casos listados para quando o grafo for null: formula null, formula com 1 char, formula faltando fechar parenteses ou formula com parenteses fechados(inválida)
  61.     [(null? formula) (display formula)] ;se o grafo não for null e a formula for null, incompatibilidade
  62.     [(equal? "(" (first formula)) ;caso ache uma expressão entre ()
  63.      (begin
  64.           (cond
  65.             [(= 0 vezes) (set! inicio grafo)]) ;salva o grafo antes de entrar na expressão entre parênteses e vezes guarda o numero de (
  66.           (set! vezes (add1 vezes))
  67.           (if(equal? "(" (first(rest formula))) ; se o char seguinte for outro (, chama analise com o restante da formula em que o primeiro é (
  68.                (analise (rest formula) grafo custos parenteses)
  69.                (if(equal? #t (acharCaminho (first (rest formula)) (weights (first (map first grafo)) grafo))) ;se não for (, procura um caminho no grafo. Caso ache, chama analise com o primeiro elemento da formula sendo o custo verificado e armazena o nó inicial e o custo inicial para o caso de iterações
  70.                   (analise (rest formula) grafo (constroiLista vezes (first (rest formula)) custos) (constroiLista vezes (next (first (rest formula)) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) parenteses)) ;parenteses recebe constroiLista que recebe o estado depois do custo inicial e qtd de parenteses abertos
  71.                   (percorreFormula formula (- vezes 1) 0 custos parenteses))))] ;caso a expressão entre () seja inválida, ainda há chances de ser compatível
  72.     [(equal? ")" (first formula)) ;caso ache o fim da expressão entre ()
  73.      (begin
  74.        (set! vezes (sub1 vezes)) ;vezes diminui até a qtd de ) ser igual a de (
  75.        (if(null? (rest formula)) ;se a formula for um unico char
  76.           (analise (rest formula) grafo (rest custos) (rest parenteses)) ;chama a analise com a formula null e faz o rest de custos e parenteses, deixando ambos com o valor null pois ) será o último da expressão
  77.           (if(equal? "*" (first(rest formula))) ;caso ache uma iteração depois do )
  78.              (if(equal? #t (acharCaminho (first custos) (weights (first (map first grafo)) grafo))) ;procura o caminho armazenado em custos no nó atual do grafo
  79.                 (if(equal? (first parenteses) (next (first custos) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo))) ;verifica se o destino é o mesmo armazenado na lista parenteses
  80.                    (analise (rest(rest formula)) (rest grafo) (rest custos) (rest parenteses)) ;achou a iteração e chama a analise com a formula depois de * e o grafo saindo da iteração
  81.                    (display formula)) ;achou o caminho mas não faz iteração, então é incompatível
  82.                 (percorreFormula (rest formula) (- vezes 1) 0 custos parenteses)) ;se o caminho para a iteração não existe, ainda há uma chance da formula ser compatível
  83.              (if(equal? "?" (first(rest formula))) ;se encontra uma condicional depois do ?
  84.                 (analise (rest(rest formula)) inicio (rest custos) (rest parenteses)) ;chama analise com a formula depois de ? e retira o primeiro elemento de custos e parenteses      
  85.                 (analise (rest formula) grafo (rest custos) (rest parenteses))))))] ;não achou nada que torna a fórmula inválida por enquanto, chama a analise com o restante da formula, custos e parenteses
  86.     [(null? (rest formula)) (if(equal? #t (acharCaminho (first formula) (weights (first (map first grafo)) grafo))) (if(null? (kids (next (first formula) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) grafo)) #t (display formula)) (display formula))] ;verifica a última letra da fórmula, se ela é um custo válido e verifica se o nó que se chega a partir do custo é folha. Se for folha, grafo e fórmula são correspondetes.
  87.     [else (if(equal? #t (acharCaminho (first formula) (weights (first (map first grafo)) grafo))) ;verifica se a primeira casa da fórmula atual(muda através da recursão) é um custo válido pro primeiro nó do grafo atual
  88.              (if(equal? ";" (first(rest formula))) ;Se a próxima casa da fórmula é ;
  89.              (analise (rest (rest formula)) (proximo (next (first formula) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) grafo) custos parenteses) ;Seta o inicio da proxima formula para o elemento depois de ; e, o grafo resultante é aquele gerado depois de tomar o caminho com o custo da primeira casa da fórmula atual
  90.              (if(equal? "?" (first(rest formula))) ;Se a próxima casa da fórmula é ?
  91.                 (analise (rest (rest formula)) grafo custos parenteses) ;Início da proxima formula é o primeiro elemento depois de ?. Se o inicio da primeira formula é um custo válido, então executará o comando com custo depois de ?, se ele existir no grafo
  92.                 (if(equal? "U" (first(rest formula))) ;Se a próxima casa da fórmula é U
  93.                    (analise (rest (rest (rest formula))) (proximo (next (first formula) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) grafo) custos parenteses) ;Se a primeira casa da formula existe, não precisa checar a casa depois de U. O inicio da proxima formula é setado para depois do elemento que se localiza depois de U. O grafo resultante realiza o movimento com o custo da primeira casa da formula.
  94.                    (if(equal? "*" (first(rest formula))) ;Se a próxima casa da fórmula é *
  95.                       (if(equal? (first (map first grafo)) (next (first formula) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo))) ;Se o primeiro nó do grafo atual possui o custo(primeira casa da fórmula) e se o destino desse caminho é o próprio nó
  96.                          (analise (rest (rest formula)) (rest grafo) custos parenteses) ;Foi checado que a iteração existe, então o inicio da fórmula é o elemento depois de * e o grafo resultante corta o caminho que aponta para o mesmo nó para não ficar preso em um loop
  97.                          (percorreFormula formula (- vezes 1) 0 custos parenteses)) ;Se o custo do primeiro elemento da fórmula não tiver como destino o primeiro nó do grafo atual, então a fórmula e o grafo não são correspondentes
  98.                       (if(equal? ")" (first(rest formula))) ;caso o proximo elemento da formula indique o fim de uma expressão entre ()
  99.                          (analise (rest formula) (proximo (next (first formula) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) grafo) custos parenteses) ;faz a recursão com o restante da formula e percorre o grafo partindo do custo inicial da formula atual
  100.                          (display formula)))))) ;se encontrou algum elemento inválido na fórmula
  101.              (if(equal? "U" (first(rest formula))) ;Se não achou o primeiro elemento da disjunção, checa o segundo elemento
  102.                 (if(equal? #t (acharCaminho (first (rest (rest formula))) (weights (first (map first grafo)) grafo))) ;Se o segundo elemento da disjunção for um custo válido para o primeiro nó do grafo atual
  103.                    (analise (rest (rest (rest formula))) (proximo (next (first (rest (rest formula))) (weights (first (map first grafo)) grafo) (kids (first (map first grafo)) grafo)) grafo) custos parenteses) ;A disjunção é válida e o inicio da formula se localiza depois do fim da disjunção e o caminho do segundo custo é feito no grafo atual, gerando um novo grafo
  104.                    (if(equal? "(" (first (rest (rest formula)))) ;caso o segundo elemento da disjunção seja uma expressão entre ()
  105.                       (analise (rest (rest formula)) grafo custos parenteses) ;faz a recursão com a formula depois de U
  106.                       (display formula))) ;Se o segundo custo da disjunção também não existe, o grafo e a fórmula não são correspondentes
  107.                 (if(> vezes 0) ;se não tiver U na casa seguinte, pode ser uma expressão entre () que não terminou ainda
  108.                    (percorreFormula formula (- vezes 1) 0 custos parenteses) ;ainda há chance de ser compatível
  109.                    (display formula));Se não fizer parte de uma disjunção, então o grafo e a fórmula não são correspondentes
  110.           ))]))
  111.  
  112. (define (percorreFormula formula condicao passou custos parenteses) ;sabe-se que uma parte da formula é inválida, percorrendo expressões entre () até chegar na condicao
  113.   (cond
  114.     [(null? formula) (display formula)] ;grafo não é null e formula é, logo incompatibilidade
  115.     [(null? (rest formula)) (if(equal? ")" (first formula)) #t (display formula))] ;se a formula for um unico char, será compativel se indicar o fim de uma expressão entre () e será incompatível caso contrário
  116.     [(= condicao vezes) (if(equal? "U" (first formula)) ;chegou na condicao de parada e verifica se achou uma disjunção
  117.             (percorreFormula (rest formula) condicao 1 custos parenteses) ;procura o proximo elemento depois de U
  118.             (if(equal? "?" (first formula)) ;verifica se achou uma condicional
  119.                (percorreFormula (rest formula) condicao 1 custos parenteses) ;procura o proximo elemento depois de ?
  120.                (if(= 1 passou) ;já achou U ou ?
  121.                   (analise formula inicio null null) ;verifica se a formula pode ser valida
  122.                     (display formula))))] ;formula e grafo incompativeis
  123.     [(equal? "U" (first formula)) ;se o primeiro elemento da formula já indicar disjunção
  124.              (analise (rest formula) inicio null null)] ;verifica se a formula é compativel
  125.     [else (if(equal? ")" (first formula)) ;fim de uma expressão entre ()
  126.             (begin
  127.             (set! vezes (sub1 vezes)) ;diminui a quantidade de (
  128.             (percorreFormula (rest formula) condicao passou custos parenteses)) ;faz a recursão com o restante da formula
  129.             (if(equal? ";" (first (rest formula))) ;verifica se é uma sequencia de valores
  130.                (pulaParenteses formula custos parenteses 1) ;chama BuscaParenteses já encontrando um valor invalido, mas ainda pode ser uma formula compativel
  131.                (percorreFormula (rest formula) condicao passou custos parenteses)))])) ;caso não tenha encontrado nem ) e nem ;, faz a recursão com o restante da formula
  132.  
  133. (define (percorreCustos custos) ;percorre a lista de custos até chegar ao final dela
  134.   (cond
  135.     [(null? (rest custos)) custos]
  136.     [else (percorreCustos (rest custos))]))
  137.  
  138. (define (percorreParenteses parenteses) ;percorre a lista de parenteses até chegar no final dela
  139.   (cond
  140.     [(null? (rest parenteses)) parenteses]
  141.     [else (percorreParenteses (rest parenteses))]))
  142.  
  143. (define (formula str) ;transforma uma string em uma lista
  144.   (map string (string->list str)))
  145.  
  146.  
  147. ;EXEMPLOS
  148. ;DESCOMENTAR UMA LINHA DE FORMULA E UMA LINHA DE GRAFO DE CADA EXEMPLO PARA VER A EXECUÇÃO DE CADA
  149. ;RUN E ESCREVER NO CONSOLE (analise x Graph null null) para chamar a função analise que checa se o grafo e a fórmula são compatíveis
  150. ;analise RETORNARÁ #t SE FOREM COMPATÍVEIS OU RETORNARÁ O PONTO DE INÍCIO DA DESCOMPATIBILIDADE NA FÓRMULA
  151.  
  152. ;PRIMEIRO EXEMPLO
  153. ;(define x (formula "x;y"))
  154. ;(define Graph '(("A" "B" "x") ("B" "D" "y")))
  155. ;(define Graph '(("A" "B" "x")))
  156. ;(define Graph '(("A" "B" "y") ("B" "D" "x")))
  157. ;(define Graph '(("A" "B" "x") ("C" "D" "y")))
  158.  
  159. ;SEGUNDO EXEMPLO
  160. ;(define x (formula "x?y"))
  161. ;(define Graph '(("A" "B" "x") ("A" "C" "y")))
  162. ;(define Graph '(("A" "B" "x")))
  163. ;(define Graph '(("A" "C" "y")))
  164.  
  165. ;TERCEIRO EXEMPLO
  166. ;(define x (formula "x*"))
  167. ;(define Graph '(("A" "A" "x")))
  168. ;(define Graph '(("A" "B" "x")))
  169. ;(define Graph '(("A" "A" "y")))
  170.  
  171. ;QUARTO EXEMPLO
  172. ;(define x (formula "xUy"))
  173. ;(define Graph '(("A" "B" "x")))
  174. ;(define Graph '(("A" "C" "y")))
  175. ;(define Graph '(("A" "B" "x") ("A" "C" "y")))
  176. ;(define Graph '(("A" "B" "z")))
  177.  
  178. ;QUINTO EXEMPLO
  179. ;(define x (formula "(x;y)?z"))
  180. ;(define Graph '(("A" "B" "x") ("A" "C" "z") ("B" "C" "y") ))
  181. ;(define Graph '(("A" "B" "x") ("A" "C" "z") ))
  182. ;(define Graph '(("A" "C" "z") ("B" "C" "y") ))
  183. ;(define Graph '(("A" "B" "x") ("B" "C" "y") ))
  184.  
  185. ;SEXTO EXEMPLO
  186. ;(define x (formula "(x;y)Uz"))
  187. ;(define Graph '(("A" "B" "x") ("A" "C" "z") ("B" "C" "y") ))
  188. ;(define Graph '(("A" "B" "x") ("A" "C" "z") ))
  189. ;(define Graph '(("A" "C" "z") ("B" "C" "y") ))
  190. ;(define Graph '(("A" "B" "x") ("B" "C" "y") ))
  191.  
  192. ;SÉTIMO EXEMPLO
  193. ;(define x (formula "(x;y)*"))
  194. ;(define Graph '(("A" "B" "x") ("B" "C" "y") ("C" "B" "x")))
  195. ;(define Graph '(("A" "B" "x")))
  196. ;(define Graph '(("A" "B" "x") ("B" "C" "y")))
  197.  
  198. ;OITAVO EXEMPLO
  199. ;(define x (formula "x?(y;z)*"))
  200. ;(define Graph '(("A" "B" "x") ("A" "C" "y") ("C" "D" "z") ("D" "C" "y")))
  201. ;(define Graph '(("A" "B" "x") ("A" "C" "y") ("C" "D" "z") ("D" "C" "y") ("D" "E" "x")))
  202. ;(define Graph '(("A" "C" "y") ("C" "D" "z") ("D" "C" "y")))
  203. ;(define Graph '(("A" "B" "x") ("C" "D" "z") ("D" "C" "y")))
  204. ;(define Graph '(("A" "B" "x") ("A" "C" "y") ("D" "C" "y")))
  205.  
  206. ;NONO EXEMPLO
  207. ;(define x (formula "x?(x;y)*"))
  208. ;(define Graph '(("A" "B" "x") ("B" "D" "y") ("D" "B" "x")))
  209. ;(define Graph '(("B" "D" "y") ("D" "B" "x")))
  210. ;(define Graph '(("A" "B" "x") ("B" "D" "y")))
  211. ;(define Graph '(("A" "B" "x") ("D" "B" "x")))
  212.  
  213. ;ÚLTIMO EXEMPLO
  214. ;(define Graph '(("A" "B" "x") ("B" "C" "y") ("C" "D" "z")))
  215. ;(define x (formula "(w;z;r)U(x;y;z)"))
  216. ;(define x (formula "wU(x;y;z)"))
  217. ;(define x (formula "wUx"))
  218. ;(define x (formula "x;y;z"))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement