Five Ones
Five Ones accepts all binary strings that have multiples of five ones. Interestingly, this is the same
automaton as drawn as a \(5n+k\) automaton: only the initial state differentiates between these. Here, the
given examples disambiguate this case. One positive example is sufficient; however, four negative examples
would be required without any positive example.
Annotated Image
Program Specification
;;;
;;; Preamble
;;;
( set-logic ALL )
;;;
;;; State Definitions
;;;
( define-fun is-state (( q Int )) Bool
( and ( < ( - 1 ) q ) ( < q 6 )))
( define-fun is-accepting (( q Int )) Bool
( or ( = q 3 )))
( 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 ( = 2 ( T 1 "1" )))
( assert ( = 2 ( T 2 "0" )))
( assert ( = 1 ( T 3 "1" )))
( assert ( = 3 ( T 3 "0" )))
( assert ( = 4 ( T 2 "1" )))
( assert ( = 3 ( T 5 "1" )))
( assert ( = 5 ( T 4 "1" )))
( assert ( = 4 ( T 4 "0" )))
( assert ( = 5 ( T 5 "0" )))
;; Negative transitions
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "0" ) ( = symb "1" )))
( = 0 ( T 1 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "0" ) ( = symb "1" )))
( = 0 ( T 2 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "1" ) ( = symb "0" )))
( = 0 ( T 3 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "1" ) ( = symb "0" )))
( = 0 ( T 4 symb )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "1" ) ( = symb "0" )))
( = 0 ( T 5 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 "11111" ))
;; Negative
( assert ( not ( exec-dfa IS "11011" )))
( assert ( not ( exec-dfa IS "1111" )))
;;;
;;; Postamble
;;;
( check-sat )
( get-model )
Synthesized Program
sat
(
( define-fun IS () Int
3 )
( define-fun T (( x!0 Int ) ( x!1 String )) Int
( let (( a!1 ( or ( and ( not ( <= 1 x!0 )) ( = x!1 "0" ) ( not ( = x!1 "1" )))
( and ( not ( <= 1 x!0 )) ( not ( = x!1 "0" )) ( not ( = x!1 "1" )))
( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 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 )
( <= 3 x!0 )
( <= 4 x!0 )
( not ( <= 5 x!0 ))
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( <= 5 x!0 )
( not ( = x!1 "0" ))
( not ( = x!1 "1" )))))
( a!2 ( or ( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" )))
( and ( <= 1 x!0 ) ( not ( <= 2 x!0 )) ( = x!1 "1" ))))
( a!3 ( ite ( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" )))
1
13 )))
( let (( a!4 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 x!0 ))
( = x!1 "1" ))
1
( ite a!2 2 a!3 ))))
( let (( a!5 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" )))
3
a!4 )))
( let (( a!6 ( ite ( and ( <= 1 x!0 ) ( <= 2 x!0 ) ( not ( <= 3 x!0 )) ( = x!1 "1" ))
4
a!5 )))
( let (( a!7 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( not ( <= 5 x!0 ))
( = x!1 "1" ))
5
( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( <= 5 x!0 )
( = x!1 "1" ))
3
a!6 ))))
( let (( a!8 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( not ( <= 5 x!0 ))
( = x!1 "0" )
( not ( = x!1 "1" )))
4
a!7 )))
( let (( a!9 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( <= 5 x!0 )
( = x!1 "0" )
( not ( = x!1 "1" )))
5
a!8 )))
( ite a!1 0 a!9 )))))))))
)