Invariante para loop aninhado no programa de multiplicação de matrizes


7

Estou fazendo uma tese de pós-graduação sobre a comprovação da correção do programa para multiplicar 2 matrizes usando a lógica Hoare. Para fazer isso, preciso gerar o loop invariável para aninhado para este programa:

for i = 1:n
    for j = 1:n
        for k = 1:n
            C(i,j) = A(i,k)*B(k,j) + C(i,j);
        end
    end
end

Tentei encontrar o invariante para o loop interno primeiro, mas não consigo encontrar o verdadeiro até agora. Alguém pode me ajudar a encontrar o invariante para o programa acima?

Respostas:


11

Você precisa da linha C(i:j) = 0imediatamente antes do loop mais interno; caso contrário, o código está incorreto.

Supondo que a linha esteja no lugar, aqui está a invariante (mais forte possível) imediatamente antes da atribuição no loop mais interno: (Sim, a coisa toda.) O invariante logo após a atribuição tem no lugar de na última soma, mas é idêntico.

CIJ=k=1nAIkBkJfor all I and J such that 1I<i and 1Jnand   CiJ=k=1nAikBkJfor all J such that 1J<jand   Cij=K=1k1AiKBKj.
kk1

Prof, enviei-lhe um email. Desculpa se eu atrapalho você. :)
asn32

2

Não existe o "invariável": qualquer loop tem muitos invariantes. Você precisa encontrar um invariante interessante. Como você está tentando provar que o loop calcula uma multiplicação de matrizes, seu invariante deve implicar que quando , os coeficientes de são os do produto da matriz , ou seja, É bastante natural para especializar esta propriedade de e de conjecturar uma invariante para as espiras externas e meio:i=j=k=nCA×B

i[1,n],j[1,n],C(i,j)=k=1nA(i,k)B(k,j)
ij
  • j[1,n],C(i,j)=k=1nA(i,k)B(k,j) no loop externo
  • C(i,j)=k=1nA(i,k)B(k,j) no loop do meio

Cada execução do loop interno adiciona o ésimo termo à soma, o que leva ao invariante proposto: É fácil ver que, se essa invariante é mantida, a invariante proposta para o loop intermediário é mantida e, a partir disso, a invariante proposta para o loop externo é mantida e o programa faz o que é esperado.k

C(i,j)=l=1kA(i,l)B(l,j)

O que falta provar é a condição inicial. Você precisa provar que , ou seja, na entrada do programa. É melhor inicializar para que seja assim. Como alternativa, você pode obter essa propriedade fazendo a inicialização dentro do loop intermediário, imediatamente antes de entrar no loop interno.i,j,C(i,j)=l=10A(i,l)B(l,j)i,j,C(i,j)=0C

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.