One of Each
One of Each only accepts strings that have one A and one B; that is, only AB and BA.
Note how the top of this image is slightly defocused, which the feature extraction is robust to.
Annotated Image
Program Specification
;;;
;;; Preamble
;;;
( set-logic ALL )
;;;
;;; State Definitions
;;;
( define-fun is-state (( q Int )) Bool
( and ( < ( - 1 ) q ) ( < q 5 )))
( 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 2 "A" )))
( assert ( = 3 ( T 1 "B" )))
( assert ( = 3 ( T 4 "A" )))
( assert ( = 4 ( T 2 "B" )))
;; Negative transitions
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "B" )))
( = 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 )))))
( assert ( forall (( symb String ))
( => ( not ( or ( = symb "A" )))
( = 0 ( T 4 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 "AB" ))
;; Negative
( assert ( not ( exec-dfa IS "BB" )))
;;;
;;; Postamble
;;;
( check-sat )
( get-model )
Synthesized Program
sat
(
( define-fun IS () Int
2 )
( define-fun T (( x!0 Int ) ( x!1 String )) Int
( let (( a!1 ( or ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 x!0 ))
( not ( = x!1 "A" ))
( not ( = x!1 "B" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 x!0 ))
( = x!1 "A" )
( not ( = x!1 "B" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( not ( = x!1 "A" ))
( not ( = x!1 "B" )))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( not ( = x!1 "A" ))
( not ( = x!1 "B" )))
( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( = x!1 "A" )
( not ( = x!1 "B" )))
( and ( not ( <= 1 x!0 )) ( = x!1 "A" ) ( not ( = x!1 "B" )))
( and ( not ( <= 1 x!0 )) ( = x!1 "B" ))
( and ( <= 1 x!0 ) ( <= 2 x!0 ) ( <= 3 x!0 ) ( <= 4 x!0 ) ( = x!1 "B" ))
( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( not ( <= 4 x!0 ))
( = x!1 "B" ))
( and ( <= 1 x!0 )
( not ( <= 2 x!0 ))
( not ( = x!1 "A" ))
( not ( = x!1 "B" )))
( and ( not ( <= 1 x!0 )) ( not ( = x!1 "A" )) ( not ( = x!1 "B" )))))
( a!2 ( or ( and ( <= 1 x!0 )
( <= 2 x!0 )
( <= 3 x!0 )
( <= 4 x!0 )
( = x!1 "A" )
( not ( = x!1 "B" )))
( and ( <= 1 x!0 ) ( not ( <= 2 x!0 )) ( = x!1 "B" ))))
( a!3 ( ite ( and ( <= 1 x!0 )
( <= 2 x!0 )
( not ( <= 3 x!0 ))
( = x!1 "A" )
( not ( = x!1 "B" )))
1
7 )))
( let (( a!4 ( ite ( and ( <= 1 x!0 ) ( <= 2 x!0 ) ( not ( <= 3 x!0 )) ( = x!1 "B" ))
4
( ite a!2 3 a!3 ))))
( ite a!1 0 a!4 ))))
)