Multiple of Three
Multiple of Three accepts all binary strings that are a multiple of three. This automaton was transcribed
from the Wikipedia page on deterministic finite automaton. The "whiteboard noise" is getting strong; pieces
of previous automata are beginning to become clearly visible in the background.
Annotated Image
Program Specification
;;;
;;; Preamble
;;;
( set-logic ALL )
;;;
;;; State Definitions
;;;
( define-fun is-state (( q Int )) Bool
( and ( < ( - 1 ) q ) ( < q 4 )))
( define-fun is-accepting (( q Int )) Bool
( or ( = q 1 )))
( declare-fun IS () Int )
( assert ( is-state IS ))
( assert ( not ( = 0 IS )))
;;;
;;; Transition Definitions
;;;
( declare-fun T ( Int String ) Int )
;; All transitions must go to a valid state
( assert ( forall (( q Int ) ( symb String ))
( => ( is-state q ) ( is-state ( T q symb )))))
;; It must not be possible to leave the zero state
( assert ( forall (( symb String )) ( = 0 ( T 0 symb ))))
;; Defined transitions
( assert ( = 1 ( T 1 "0" )))
( assert ( = 1 ( T 2 "1" )))
( assert ( = 2 ( T 1 "1" )))
( assert ( = 2 ( T 3 "0" )))
( assert ( = 3 ( T 2 "0" )))
( assert ( = 3 ( T 3 "1" )))
;; Negative transitions
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "0" ) ( = symb "1" )))
( = 0 ( T 1 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "1" ) ( = symb "0" )))
( = 0 ( T 2 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "0" ) ( = symb "1" )))
( = 0 ( T 3 symb )))))
;;;
;;; Examples
;;;
( 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 )))))
;; Positive
( assert ( exec-dfa IS "1001" ))
( assert ( exec-dfa IS "0011" ))
;; Negative
( assert ( not ( exec-dfa IS "0100" )))
( assert ( not ( exec-dfa IS "0001" )))
;;;
;;; Postamble
;;;
( check-sat )
( get-model )
Synthesized Program
sat
(
( define-fun IS () Int
1 )
( define-fun T (( x!0 Int ) ( x!1 String )) Int
( let (( a!1 ( or ( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))
( and ( not ( <= 1 x!0 )) ( not ( = x!1 "0" )) ( not ( = x!1 "1" )))
( and ( not ( <= 1 x!0 )) ( = x!1 "0" ) ( not ( = x!1 "1" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))
( and ( not ( <= 1 x!0 )) ( = x!1 "1" ))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))))
( a!2 ( or ( and ( <= 1 x!0 ) ( <= 2 x!0 ) ( <= 3 x!0 ) ( = x!1 "1" ))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" )))))
( a!3 ( or ( and ( <= 1 x!0 ) ( not ( <= 2 x!0 )) ( = x!1 "1" ))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( = x!1 "0" )
( not ( = x!1 "1" )))))
( a!4 ( or ( and ( <= 1 x!0 ) ( <= 2 x!0 ) ( not ( <= 3 x!0 )) ( = x!1 "1" ))
( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" ))))))
( ite a!1 0 ( ite a!2 3 ( ite a!3 2 ( ite a!4 1 15 ))))))
)