• No results found

7 English summary

In document Kunst i tall 2019 (sider 143-148)

Para transformar o modelo foram especificadas um número avultado de regras que cooperativamente permitem obter o código Prolog final. Nesta secção apresentar-se-á, de forma intuitiva, as regras envolvidas na transformação de diversos trechos de um modelo especificado através da sintaxe textual do SATEL⊕EAPN. Para que a descrição não se fique pela forma intuitiva (logo informal), à medida que forem descritas as regras indicar-se-ão apontadores para o apêndice das regras em análise, especificadas na sintaxe do DSLTrans.

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

Posto isto, atente-se no exemplo da figura 4.3. Na transformação aqui envolvida, note-se que é um gerador de naturais cujo nome da operação associada é③❡r♦ e cujo sort do resultado é claramente ♥❛t (naturais). Da figura depreende-se então que, em primeira análise, num gerador, dito constante, cria-se um predicado cujo nome é o sort do result, cuja aridade é um e o único argumento é um functor sem argumentos cujo nome é o nome do gerador.

zero -> nat nat(zero).

$L)

‘ ’).

2 1

Figura 4.3: Transformação do gerador

De uma forma mais geral, atente-se na figura 4.4. Neste exemplo tem-se um ge- rador que possui argumentos de determinado sort. Repare-se que a regra a aplicar é similar à anterior com as devidas extensões/generalizações. Com efeito, aqui o sort do resultado (nat) volta a ser o nome do functor da cabeça de uma cláusula. Neste exemplo é necessário uma cláusula porque é necessário impor condições sobre os ar- gumentos.

O functor da cabeça volta a imbricar o functor com o nome do gerador, no entanto, este agora tem aridade superior a zero. Os argumentos deste functor devem ser tantas variáveis quantos os argumentos do gerador, na mesma ordem de correspondência. No corpo da cláusula é necessário impôr que as variáveis criadas por via de cada um dos argumentos do gerador, sejam exactamente do sort do argumento correspondente (ex. fluxo 3 e 5) da figura.

suc : nat -> nat nat(suc(X1)):-nat(X1).

$L) ‘ ’). 4 3 5 6

Figura 4.4: Transformação do gerador

Da mesma forma e já generalizando, na figura 4.5, ao invés de se ter apenas um argumento, tem-se dois; um para o elemento a adicionar à lista e outro para a lista onde vai ser adicionado à cabeça. Assim pode-se concluir que se deve criar um predicado com aridade um quando o gerador é constante e uma cláusula quando o gerador tem

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

argumentos. O nome do functor da cabeça é, nesse caso, o nome do sort do resultado, e contém um functor com tantas variáveis quantas os argumentos do gerador; variáveis essas que devem ser restringidas quanto ao seu sort no corpo da cláusula.

cons : nat list -> list list(cons(X1,X2)):-nat(X1), list(X2).

$L)

‘ ’).

7 8

Figura 4.5: Transformação do gerador

Para a transformação dos geradores são assim necessárias regras para as seguintes tarefas:

• criação de um objecto Clause por cada gerador • criação de um objecto Head para a Clause • criação de um objecto Body para a Clause • criação do functor com o nome do gerador (A)

• criação do functor com o nome do sort do resultado (B)

• criação de variáveis por cada argumento do gerador, para colocar em Head (V) • criação de functores por cada argumento do gerador, para colocar em Body (FV) • relacionar Clause com Head

• relacionar Clause com Body • relacionar Functores (A) e (B)

• relacionar Functores (FV) com as Variáveis respectivas (V) • relacionar object Clause com o objecto Model

Tendo já sido definidas as regras para os geradores de um ADT, observe-se a figura 4.6. A formulação empírica presente na regra corresponde à transformação de um axioma sobre uma operação de um ADT.

Este é um axioma sobre a operação♥❜❖❝✉rr que pode ser aplicado quando se veri- fica a condição a azul. Em cima, a laranja, tem-se o lado esquerdo da regra e a vermelho a reescrita dos termos que estão à esquerda.

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

eq ($E, $H) = false => nbOcurr ($E, cons($H, $L)) = nbOcurr($E, $L)

:- nat(E), nat(H), list(L) ,

eval(nbOcurr(E, cons (E, H)), R)

eval(eq(E, H), R1), eval(false, R1),

eval(nbOcurr(E, H), R) .

‘ ’).

Figura 4.6: Transformação dos axiomas das operações

Posto isto, na transformação de um axioma deve ser criada uma cláusula. Nesta cláusula, a cabeça deve ser um functor com nome ’❡✈❛❧’ que tem como primeiro ar- gumento aquilo que se pretende reescrever e como segundo argumento uma variável que conterá o resultado da avaliação/redução do primeiro. Em particular, doravante, os functores ’❡✈❛❧’ funcionam sempre desta forma.

O corpo da cláusula deve conter nesta ordem, os functores que restringem o sort dos elementos envolvidos na operação seguidos de functores ’❡✈❛❧’ para ambos os mem- bros das equações das condições do axioma. Neste caso adiciona-se um functor ’❡✈❛❧’ que deve avaliar ❡q✭❊✱❍✮ e colocar o resultado numa variável (R1) e coloca-se outro functor que avalia❢❛❧s❡ e tenta unificar R1 para ambos os predicados. Por fim coloca- se um functor ❡✈❛❧ que avalia o lado direito da equação do axioma e que unificará o resultado com R (que é o resultado do lado esquerdo). Se houvesse mais condições, os respectivos predicados deveriam ser postos antes deste functor para que as condições fossem todas avaliadas previamente.

A esta estratégia há pelo menos duas adições a fazer. Em caso de condições que sejam inequações é necessário que para ambos os resultados (lado esquerdo e direito) sejam criadas variáveis diferentes, e garantir que elas não unificam (e.g. R1\=R2, em que R2 é a variável correspondente ao lado direito e R1 ao lado esquerdo).

A segunda adição tem que ver com o facto de os geradores terem que poder ser avaliados. Por exemplo em❡✈❛❧✭❢❛❧s❡✱❘✶✮, onde consta o gerador ❢❛❧s❡ dos booleanos, quer-se que R1 unifique com❢❛❧s❡, mas se um fosse um natural (e.g. eval(suc(X),R2)) querer-se-ia que R2 unificasse com suc(X), em que X já estivesse avaliado. Foi para este efeito que se criaram regras que resolvem os exemplos das figuras 4.7 e 4.8, as quais serão explicadas em seguida.

Posto isto foram criadas regras para o seguinte:

• Criação de Clause para cada CondEquation (Axioma) • Criação de Body e Head para cada CondEquation

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

• Criação de functores eval para cada lado de uma equação ou inequação • Criação de variáveis para as variáveis envolvidas num axioma

• Criação de variáveis para os diversos resultados

• Criação de functores que representem os CTerm (e.g. suc(suc(zero))) • Criação das relações nextTerm entre ConditionAtom (Condições) • Criação de functores para restringir o sort de cada variável

• Criação de functores ’eval’ para os geradores tal como indicado nas figuras 4.7 e 4.8.

zero -> nat eval(zero,zero).

$L)

‘ ’).

1

Figura 4.7: Transformação do gerador

suc :nat -> nat eval(suc(X1),suc(XX1)):-eval(X1,XX1).

$L)

‘ ’).

Figura 4.8: Transformação do gerador

Por fim, tem-se regras para transformar a especificação das intenções de teste. O código Prolog pretendido para a transformação dos axiomas das intenções de teste é muito similar ao código pretendido para os axiomas dos ADT. Exceptua-se apenas pelo facto de as intenções de teste poderem dar origem a cláusulas sem corpo, como no caso da figura 4.9.

HML(T) in TickIntention in ( [top], TickIntention’).

1 2

3

Figura 4.9: Transformação das intenções de teste

Em relação aos axiomas das intenções de teste quer-se que estes resultem numa cláusula cuja cabeça é um functor ’✐♥’ (fluxo 1 da figura 4.9), com aridade 2, cujos ar- gumentos são primeiramente uma lista com o padrão de execução do sistema (fluxo

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

2), e o segundo é um quoted atom com o nome da intenção (fluxo 3). Caso existam con- dições os correspondentes functores ’❡✈❛❧’ devem ser colocados no corpo da cláusula (e.g. condições a azul e a verde na figura 4.10).

O padrão de execução pode conter o objecto❍▼▲❚♦♣ (que se representará com um functort♦♣ sem argumentos) e eventos que devem ser representados por um par orde- nado em que o primeiro elemento é um functor correspondente ao método de input e o segundo é um functor correspondente à gate de output; ambos podem conter argu- mentos correspondentes aos do método e da gate, respectivamente (e.g. a sublinhado na figura 4.10).

{lt($Counter, suc^3(zero))} = {t r u e} , $t in TickIntention

=>

$t . HML( { <mark with time($Counter ) > } T ) inMarkIntention ;

in([T,(mark,time(Counter)),top], 'MarkIntention'):- in(F,'TickIntention'),

flatten(F,T),

eval(algEquality(lt(Counter,suc(suc(suc(zero)))), true), true).

‘ ’). 1 2 3 4 5

Figura 4.10: Transformação das intenções de teste

Assim se conclui, que em relação à transformação das intenções de teste é necessá- rio criar regras para o seguinte:

• Criação do functor ’in’ para cada axioma

• Criação da lista que contém o padrão de execução

• Criação de um ’QuotedAtom’ referente ao nome da intenção • Criação de functor eval para ConditionAtom (Condições)

• A cada Inclusion que seja ConditionAtom deve estar associado o predicado flat- ten

• O necessário para transformar CompositeTerm (e.g. suc(suc(zero))). É equiva- lente aos CTerm no contexto das intenções de teste

• O necessário para construir todo o ConditionAtom

• Criação de todas as relações necessárias para associar os objectos 70

4. ABORDAGEM PROPOSTA/SOLUÇÃO 4.7. Modelo de transformação

In document Kunst i tall 2019 (sider 143-148)