Model Checking
1 Model Checking
1.1 TLC (LAMPORT, 2002)
Explicit-State model checker
- Enumera todos os estados
- Usa um grafo direcionado com estados e transições (reachability
graph) e uma fila de estados para checar
- Provavelmente, o tipo de model checker que um de nós escreveria se fôssemos tentar (sem pesquisar um monte antes)
1.2 Apalache (KONNOV; KUKOVEC; TRAN, 2019)
Model checker simbólico
- Traduz a especificação para um conjunto de restrições (sem
quantificação)
- Usa um SMT solver para verificar a satisfabilidade das restrições
Bounded model checking
- Necessário definir um número máximo de passos (bound) para o qual gerar restrições. A verificação se dá dentro desse limite, podendo haver estados atingíveis fora desse limite que não satisfazem a propriedade.
1.3 SMT
Generalização de problemas SAT
- SAT: Problema da satisfabilidade Booleana
SMT: Satisfabilidade "modulo" teorias
- "modulo" no sentido de "dentro de"
- Permite mais elementos: inteiros, reais, arrays, etc
- "modulo" no sentido de "dentro de"
- SAT: Problema da satisfabilidade Booleana
Z3 (DE MOURA; BJØRNER, 2008):
- Leonardo de Moura e Nikolaj Bjørner
- Versão em WebAssembly
1.4 Resolvendo SMT com Z3
(declare-fun p () Bool)
(declare-fun q () Bool)
(assert (implies p q))
(assert p)
(assert (not q))
(check-sat)
Resultado: unsat
(declare-fun p () Bool)
(declare-fun q () Bool)
(assert (implies p q))
(assert p)
(assert q)
(check-sat)
Resultado: sat
1.5 Resolvendo SMT com inteiros
(declare-const a Int)
(declare-const b Int)
(assert (= (+ a b) 20))
(assert (= (+ a (* 2 b)) 10))
(check-sat)
(get-model)
Resultado: sat
1.6 Simulação simbólica
Podemos classificar não-determinismo em dois tipos:
- Não-determinismo de dados (data non-determinism)
1.to(10).oneOf()
- Não-determinismo de controle (control-flow non-determinism)
any { A, B }
Simulação simbólica:
- Model Checkers: exaustivamente checam todos os dados e
fluxos possíveis
- Simuladores aleatórios: aleatoriamente checam alguns dados e
fluxos
- Simulador simbólico: aleatóriamente checa alguns fluxos, mas considerando todos os dados possíveis
1.7 Invariância indutivas
Às vezes, podemos provar uma invariante qualquer \(I\) (também conhecida como invariante ordinária) mostrando que uma invariante indutiva \(Inv\) implica nela (\(Inv => I\)). Para isso, verificamos três coisas:
- \(Init => Inv\), ou seja,
verificar a propriedade \(Inv\) com
--max-steps=0e garantir que \(Inv\) é verdade em todos os estados iniciais
- \(Inv \land Next => Inv'\),
ou seja, verificar a propriedade \(Inv\) a partir de um estado inicial que
satisfaça \(Inv\), fazendo um passo
(
--max-steps=1)
- \(Inv => I\), ou seja, verificar
a propriedade \(I\) em todos os estados
onde \(Inv\) é verdade (
--max-steps=0).
Invariância indutiva é muito poderosa porque conseguimos uma prova completa mesmo em model-checking limitado.
1.8 Referências
DE MOURA, L.; BJØRNER, N. Z3: An efficient SMT
solverProceedings of the theory and practice of software, 14th
international conference on tools and algorithms for the construction
and analysis of systems. Anais...:
TACAS’08/ETAPS’08.Berlin, Heidelberg: Springer-Verlag, 2008
KONNOV, I.; KUKOVEC, J.; TRAN, T.-H. TLA+ model checking made
symbolic. Proc. ACM Program. Lang., v. 3, n.
OOPSLA, Oct. 2019.
LAMPORT, L. Specifying
systems: The TLA+ language and tools for hardware and software
engineers. Boston: Addison-Wesley, 2002.