Program Specification
This page will use the automaton A1 as an example, shown below.
A deterministic finite automaton
State Specification
Our automata model represents states as integers, with a unique integer for each state, along with a special “zero” state
that represents the failure case: all outgoing transitions from the zero state lead back to itself.
Formally,
We define a function
Concretely, these declarations correspond to the following in SMT-LIB2 for A1:
(define-fun is-state ((q Int)) Bool
(and (< (- 1) q) (< q 4)))
(define-fun is-accepting ((q Int)) Bool
(or (= q 3)))
as A1 has 3 defined states (so
We additionally declare the initial state
(declare-fun IS () Int)
(assert (not (= 0 IS)))
(assert (is-state IS))
Transition Specification
Determining the transition relation
(declare-fun T (Int String) Int)
We start with the general constraint that all transitions from valid states must go to valid states, that is,
(assert (forall ((q Int) (symb String))
(=> (is-state q)
(is-state (T q symb)))))
We constrain the zero state such that no transitions can leave,
(assert (forall ((symb String))
(= 0 (T 0 symb))))
We then assert all defined transitions from the annotated image; for an example transition 1 --> 2 [A]
,
(assert (= 2 (T 1 "A")))
(assert (= 2 (T 2 "B")))
(assert (= 3 (T 2 "A")))
Finally, we assert all negative transitions. That is, any symbol not specified must go to the zero state. For
the example 1 --> 2 [A]
,
(assert (forall ((symb String))
(=> (not (or (= symb "A")))
(= 0 (T 1 symb)))))
(assert (forall ((symb String))
(=> (not (or (= symb "A") (= symb "B")))
(= 0 (T 2 symb)))))
(assert (forall ((symb String))
(=> (not (or false))
(= 0 (T 3 symb)))))
Examples Specification
To handle our input examples, we first define an execution function that simulates the behavior of our
automaton,
(define-fun-rec exec-dfa ((q Int) (input String)) Bool
(ite (= 0 (str.len input))
(is-accepting q)
(exec-dfa (T q (str.at input 0)) (str.substr input 1 (- (str.len input) 1)))))
Then, each positive or negative example is just an assertion of this function starting on the initial state,
(assert (exec-dfa IS "ABBBA"))
(assert (not (exec-dfa IS "ABBB")))