{-# LANGUAGE OverloadedStrings  #-}
module Document.Tests.TrainStation 
    ( test_case )
where

    -- Modules
import Document.Tests.Suite -- (verify,find_errors,proof_obligation)

import Logic.Expr
import qualified Logic.Expr.Const as Expr
import Logic.Expr.Parser
import Logic.Proof
import Logic.QuasiQuote

import Logic.Theories.SetTheory
import Logic.Theories.FunctionTheory
import Logic.Theories.Arithmetic

    -- Libraries
import Control.Lens hiding (elements,universe,indices)
import Control.Lens.Misc hiding (combine)
import Control.Monad.State

import qualified Data.List.NonEmpty as NE
import Data.Map   as M hiding ( map )

import Test.UnitTest

test_case :: TestCase
test_case = test

test :: TestCase
test = test_cases
            "train station example"
            [ part0
            , part1
            , part2
            , part3
            , part4
            , part5
            ]
part0 :: TestCase
part0 = test_cases
            "part 0"
            [ (aCase "test 0, syntax" case0 $ Right [machine0])
            , (stringCase "test 21, multiple imports of sets" case21 result21)
            ]
part1 :: TestCase
part1 = test_cases
            "part 1"
            [ (poCase "test 1, verification" case1 result1)
            , (stringCase "test 2, proof obligation, enter/fis, in" case2 result2)
            , (stringCase "test 20, proof obligation, enter/fis, loc" case20 result20)
            , (stringCase "test 3, proof obligation, leave/fis, in'" case3 result3)
            , (stringCase "test 19, proof obligation, leave/fis, loc'" case19 result19)
            , (stringCase "test 4, proof obligation, leave/sch" case4 result4)
            ]
part2 :: TestCase
part2 = test_cases
            "part 2"
            [ (stringCase "test 5, proof obligation, leave/en/tr0/WFIS" case5 result5)
            , (stringCase "test 23, proof obligation, leave/en/tr0/EN" case23 result23)
            , (stringCase "test 24, proof obligation, leave/en/tr0/NEG" case24 result24)
            , (aCase "test 7, undeclared symbol" case7 result7)
            , (aCase "test 8, undeclared event (wrt transient)" case8 result8)
            , (aCase "test 9, undeclared event (wrt c sched)" case9 result9)
            ]
part3 :: TestCase
part3 = test_cases
            "part 3"
            [ (aCase "test 10, undeclared event (wrt indices)" case10 result10)
            , (aCase "test 11, undeclared event (wrt assignment)" case11 result11)
            , (stringCase "test 12, proof obligation leave/INV/inv2" case12 result12)
            ]
part4 :: TestCase
part4 = test_cases
            "part 4"
            [ (stringCase "test 13, verification, name clash between dummy and index" case13 result13)
            , (poCase "test 14, verification, non-exhaustive case analysis" case14 result14)
            , (poCase "test 15, verification, incorrect new assumption" case15 result15)
            ]

part5 :: TestCase
part5 = test_cases
            "part 5"
            [ (poCase "test 16, verification, proof by parts" case16 result16)
            , (stringCase "test 17, ill-defined types" case17 result17)
            , (stringCase "test 18, assertions have type bool" case18 result18)
            , (stringCase "test 22, missing witness" case22 result22)
            ]

train_sort :: Sort
train_sort = z3Sort "\\TRAIN" "sl$TRAIN" 0
train_type :: Type
train_type = Gen train_sort []

loc_sort :: Sort
loc_sort = z3Sort "\\LOC" "sl$LOC" 0
loc_type :: Type
loc_type = Gen loc_sort []

blk_sort :: Sort
blk_sort = z3Sort "\\BLK" "sl$BLK" 0
blk_type :: Type
blk_type = Gen blk_sort []

universe :: Type -> Expr
train_def :: Def
loc_def :: Def
block_def :: Def

universe t = (zlift (set_type t) ztrue)
train_def  = z3Def [] "sl$TRAIN" [] (set_type train_type) (universe train_type)
loc_def    = z3Def [] "sl$LOC" [] (set_type loc_type) (universe loc_type)
block_def  = z3Def [] "sl$BLK" [] (set_type blk_type) (universe blk_type)

_ent      :: ExprP
_ext      :: ExprP
_plf      :: ExprP
ent_var   :: Var
ext_var   :: Var
plf_var   :: Var

(_ent,ent_var)   = (Expr.var "ent" $ blk_type)
(_ext,ext_var)   = (Expr.var "ext" $ blk_type)
(_plf,plf_var)   = (Expr.var "PLF" $ set_type blk_type)

trainName :: Name
trainName = fromString'' "train0"

machine0 :: MachineAST
machine0 = newMachine trainName $ do
      theory .= (empty_theory trainName)
            {  _extends = symbol_table 
                    [ function_theory
                    , set_theory
                    , basic_theory
                    , arithmetic
                    ]
            ,  _theory'Defs = symbol_table
                    [  train_def
                    ,  loc_def
                    ,  block_def ]
            ,  _types   = symbol_table 
                    [ train_sort
                    , loc_sort
                    , blk_sort
                    ]
            ,  _theory'Dummies = symbol_table 
                            $ (map (\t -> z3Var t $ train_type) 
                                [ "t","t_0","t_1","t_2","t_3" ]
                               ++ map (\t -> z3Var t $ blk_type) 
                                [ "p","q" ])
            ,  _fact   = fromList 
                    [ ("axm0", axm0)
                    , ("asm2", axm2)
                    , ("asm3", axm3) 
                    , ("asm4", axm4) 
                    , ("asm5", axm5) 
                    ]
            ,  _consts  = symbol_table
                    [  ent_var
                    ,  ext_var
                    ,  plf_var
                    ]
            }
      inits .= fromList (zip inLbls 
             $ [ c [expr| loc = \emptyfun  |]
               , c [expr| in = \emptyset  |] ] )
      variables .= vars
      event_table .= newEvents [("enter", enter_evt), ("leave", leave_evt)]
      props .= props0
    where
        inLbls = map (label . ("in" ++) . show . (1 -)) [0..]
        axm0 = c [expr| \BLK = \{ent,ext\} \bunion PLF |]
        axm2 = c [expr| \neg ent = ext \land \neg ent \in PLF \land \neg ext \in PLF |] 
        axm3 = c [expr| \qforall{p}{}{ \neg p = ext \equiv p \in \{ent\} \bunion PLF } |]
        axm4 = c [expr| \qforall{p}{}{ \neg p = ent \equiv p \in \{ext\} \bunion PLF } |]
        axm5 = c [expr| \qforall{p}{}{ p = ent \lor p = ext \equiv \neg p \in PLF } |]

vars :: Map Name Var
vars = symbol_table [in_decl,loc_decl]

c :: Ctx
c = ctxWith [set_theory,function_theory] $ do
        [carrier| \TRAIN |]
        [carrier| \LOC |]
        [carrier| \BLK |]
        [var| ent, ext : \BLK |]
        [var| PLF : \set [\BLK] |]
        primable $ do
            [var| loc : \TRAIN \pfun \BLK |]
            [var| in : \set [\TRAIN] |]
            [var| t : \TRAIN |]

props0 :: PropertySet
props0 = create $ do
    constraint .= fromList 
            [   ( "co0"
                , Co [t_decl] 
                    $ c $ [expr| \neg t \in in \land t \in in'  \implies  loc'.t = ent |] . (is_step .~ True))
            ,   ( "co1"
                , Co [t_decl] 
                    $ c $ [expr| t \in in \land loc.t = ent \land \neg loc.t \in PLF  
                               \implies  t \in in' 
                                   \land (loc'.t \in PLF \1\lor loc'.t = ent) |] . (is_step .~ True) )
            ]
    transient .= fromList
            [   ( "tr0"
                , Tr
                    (symbol_table [t_decl])
                    (c $ [expr| t \in in |].(free_dummies .~ True)) (NE.fromList ["leave"]) 
                    (TrHint (fromList [(fromString'' "t",(train_type, c $ [expr| t' = t |] . (is_step .~ True)))]) Nothing) )
            ]
    inv .= fromList 
            [   ("inv2", c [expr| \dom.loc = in |])
            ,   ("inv1", c [expr| \qforall{t}{t \in in}{loc.t \in \BLK} |])
            ]
    safety .= fromList
            []

enter_evt :: Event
enter_evt = flip execState empty_event $ do
     indices .= symbol_table [t_decl]
     coarse_sched .= fromList
            [ ("default", zfalse )]
     raw_guards  .= fromList
            [  ("grd1", c [expr| \neg t \in in |])
            ]
     actions .= fromList
            [  ("a1", BcmSuchThat (M.elems vars)
                    (c $ [expr| in' = in \bunion \{ t \} |] . (is_step .~ True)))
            ,  ("a2", BcmSuchThat (M.elems vars)
                    (c $ [expr| loc' = loc \1| t \fun ent |] . (is_step .~ True)))
            ]

leave_evt :: Event
leave_evt = flip execState empty_event $ do
    indices   .= symbol_table [t_decl]
    coarse_sched .= singleton "c0" (c [expr| t \in in |])
    raw_guards .= fromList
            [  ("grd0", c [expr| loc.t = ext \1\land t \in in |] )
            ]
    actions .= fromList 
            [  ("a0", BcmSuchThat (M.elems vars)
                    (c $ [expr| in' = in \1\setminus \{ t \} |] . (is_step .~ True)))
            ,  ("a3", BcmSuchThat (M.elems vars)
                    (c $ [expr| loc' = \{t\} \domsub loc |] . (is_step .~ True)))
            ] 

t_decl   :: Var
in_decl  :: Var
loc_decl :: Var

(_, t_decl) = Expr.var "t" train_type
(_, _, in_decl) = prog_var "in" (set_type train_type)
(_, _, loc_decl) = prog_var "loc" (fun_type train_type blk_type)




data AxiomOption = WithPFun
    deriving Eq



path0 :: FilePath
path0 = [path|Tests/train-station.tex|]

case0 :: IO (Either [Error] [MachineAST])
case0 = (traverse.traverse %~ view' syntax) <$> parse path0

result1 :: String
result1 = unlines 
    [ "  o  train0/INIT/INV/inv1"
    , "  o  train0/INIT/INV/inv2/goal"
    , "  o  train0/INIT/INV/inv2/hypotheses"
    , "  o  train0/INIT/INV/inv2/relation"
    , "  o  train0/INIT/INV/inv2/step 1"
    , "  o  train0/INIT/INV/inv2/step 2"
    , "  o  train0/INIT/INV/inv2/step 3"
    , "  o  train0/INV/WD"
    , "  o  train0/SKIP/CO/co0"
    , "  o  train0/SKIP/CO/co1"
    , "  o  train0/co0/CO/WD"
    , "  o  train0/co1/CO/WD"
    , "  o  train0/enter/CO/co0/case 1/goal"
    , "  o  train0/enter/CO/co0/case 1/hypotheses"
    , "  o  train0/enter/CO/co0/case 1/relation"
    , "  o  train0/enter/CO/co0/case 1/step 1"
    , "  o  train0/enter/CO/co0/case 1/step 2"
    , "  o  train0/enter/CO/co0/case 2/goal"
    , "  o  train0/enter/CO/co0/case 2/hypotheses"
    , "  o  train0/enter/CO/co0/case 2/relation"
    , "  o  train0/enter/CO/co0/case 2/step 1"
    , "  o  train0/enter/CO/co0/case 2/step 2"
    , "  o  train0/enter/CO/co0/case 2/step 3"
    , "  o  train0/enter/CO/co0/case 2/step 4"
    , "  o  train0/enter/CO/co0/completeness"
    , "  o  train0/enter/CO/co1/completeness"
    , "  o  train0/enter/CO/co1/new assumption"
    , "  o  train0/enter/CO/co1/part 1/goal"
    , "  o  train0/enter/CO/co1/part 1/hypotheses"
    , "  o  train0/enter/CO/co1/part 1/relation"
    , "  o  train0/enter/CO/co1/part 1/step 1"
    , "  o  train0/enter/CO/co1/part 1/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 1/goal"
    , "  o  train0/enter/CO/co1/part 2/case 1/hypotheses"
    , "  o  train0/enter/CO/co1/part 2/case 1/relation"
    , "  o  train0/enter/CO/co1/part 2/case 1/step 1"
    , "  o  train0/enter/CO/co1/part 2/case 1/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 2/assertion/hyp6/easy"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/goal"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/hypotheses"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/relation"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/step 1"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 2/main goal/step 3"
    , "  o  train0/enter/CO/co1/part 2/completeness"
    , "  o  train0/enter/FIS/in@prime"
    , "  o  train0/enter/FIS/loc@prime"
    , "  o  train0/enter/INV/inv1"
    , "  o  train0/enter/INV/inv2/goal"
    , "  o  train0/enter/INV/inv2/hypotheses"
    , "  o  train0/enter/INV/inv2/relation"
    , "  o  train0/enter/INV/inv2/step 1"
    , "  o  train0/enter/INV/inv2/step 2"
    , "  o  train0/enter/INV/inv2/step 3"
    , "  o  train0/enter/INV/inv2/step 4"
    , "  o  train0/enter/INV/inv2/step 5"
    , "  o  train0/enter/SCH/grd1"
    , "  o  train0/leave/CO/co0/assertion/hyp6/goal"
    , "  o  train0/leave/CO/co0/assertion/hyp6/hypotheses"
    , "  o  train0/leave/CO/co0/assertion/hyp6/relation"
    , "  o  train0/leave/CO/co0/assertion/hyp6/step 1"
    , "  o  train0/leave/CO/co0/assertion/hyp6/step 2"
    , "  o  train0/leave/CO/co0/assertion/hyp6/step 3"
    , "  o  train0/leave/CO/co0/main goal/goal"
    , "  o  train0/leave/CO/co0/main goal/hypotheses"
    , "  o  train0/leave/CO/co0/main goal/relation"
    , "  o  train0/leave/CO/co0/main goal/step 1"
    , "  o  train0/leave/CO/co0/main goal/step 2"
    , "  o  train0/leave/CO/co0/main goal/step 3"
    , "  o  train0/leave/CO/co0/main goal/step 4"
    , "  o  train0/leave/CO/co0/new assumption"
    , "  o  train0/leave/CO/co1/goal"
    , "  o  train0/leave/CO/co1/hypotheses"
    , "  o  train0/leave/CO/co1/relation"
    , "  o  train0/leave/CO/co1/step 1"
    , "  o  train0/leave/CO/co1/step 2"
    , "  o  train0/leave/CO/co1/step 3"
    , "  o  train0/leave/CO/co1/step 4"
    , "  o  train0/leave/CO/co1/step 5"
    , "  o  train0/leave/CO/co1/step 6"
    , "  o  train0/leave/CO/co1/step 7"
    , "  o  train0/leave/CO/co1/step 8"
    , "  o  train0/leave/FIS/in@prime"
    , "  o  train0/leave/FIS/loc@prime"
    , "  o  train0/leave/INV/inv1"
    , "  o  train0/leave/INV/inv2/goal"
    , "  o  train0/leave/INV/inv2/hypotheses"
    , "  o  train0/leave/INV/inv2/relation"
    , "  o  train0/leave/INV/inv2/step 1"
    , "  o  train0/leave/INV/inv2/step 2"
    , "  o  train0/leave/INV/inv2/step 3"
    , "  o  train0/leave/INV/inv2/step 4"
    , " xxx train0/leave/SCH/grd0"
    , "  o  train0/leave/WD/GRD"
    , "  o  train0/tr0/TR/WFIS/t/t@prime"
    , "  o  train0/tr0/TR/leave/EN"
    , "  o  train0/tr0/TR/leave/NEG"
    , "passed 96 / 97"
    ]

case1 :: IO (String, Map Label Sequent)
case1 = verify path0 0 
        
result2 :: String
result2 = unlines 
    [ "; train0/enter/FIS/in@prime"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (not (exists ( (in@prime (set sl$TRAIN)) )"
    , "                     (and true (= in@prime (union in (mk-set@@sl$TRAIN t)))))))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; grd1"
    , "(assert (not (elem@@sl$TRAIN t in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not true))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/enter/FIS/in@prime"
    ]

case2 :: IO String
case2 = proof_obligation path0 "train0/enter/FIS/in@prime" 0

result20 :: String
result20 = unlines 
    [ "; train0/enter/FIS/loc@prime"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (not (exists ( (loc@prime (pfun sl$TRAIN sl$BLK)) )"
    , "                     (and true"
    , "                          (= loc@prime"
    , "                             (ovl@@sl$TRAIN@@sl$BLK loc (mk-fun@@sl$TRAIN@@sl$BLK t ent)))))))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; grd1"
    , "(assert (not (elem@@sl$TRAIN t in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not true))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/enter/FIS/loc@prime"
    ]

case20 :: IO String
case20 = proof_obligation path0 "train0/enter/FIS/loc@prime" 0
            
result3 :: String
result3 = unlines 
    [ "; train0/leave/FIS/in@prime"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (not (exists ( (in@prime (set sl$TRAIN)) )"
    , "                     (and true"
    , "                          (= in@prime"
    , "                             (set-diff@@sl$TRAIN in (mk-set@@sl$TRAIN t)))))))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; c0"
    , "(assert (elem@@sl$TRAIN t in))"
    , "; grd0"
    , "(assert (and (= (apply@@sl$TRAIN@@sl$BLK loc t) ext)"
    , "             (elem@@sl$TRAIN t in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not true))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/leave/FIS/in@prime"
    ]

case3 :: IO String
case3 = proof_obligation path0 "train0/leave/FIS/in@prime" 0

result19 :: String
result19 = unlines 
    [ "; train0/leave/FIS/loc@prime"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (not (exists ( (loc@prime (pfun sl$TRAIN sl$BLK)) )"
    , "                     (and true"
    , "                          (= loc@prime"
    , "                             (dom-subt@@sl$TRAIN@@sl$BLK (mk-set@@sl$TRAIN t) loc))))))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; c0"
    , "(assert (elem@@sl$TRAIN t in))"
    , "; grd0"
    , "(assert (and (= (apply@@sl$TRAIN@@sl$BLK loc t) ext)"
    , "             (elem@@sl$TRAIN t in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not true))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/leave/FIS/loc@prime"
    ]

case19 :: IO String
case19 = proof_obligation path0 "train0/leave/FIS/loc@prime" 0

result4 :: String
result4 = unlines 
    [ "; train0/leave/SCH/grd0"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; c0"
    , "(assert (elem@@sl$TRAIN t in))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not (and (= (apply@@sl$TRAIN@@sl$BLK loc t) ext)"
    , "                  (elem@@sl$TRAIN t in))))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/leave/SCH/grd0"
    ]

case4 :: IO String
case4 = proof_obligation path0 "train0/leave/SCH/grd0" 0

result5 :: String
result5 = unlines 
    [ "; train0/tr0/TR/WFIS/t/t@prime"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (not (exists ( (t@prime sl$TRAIN) ) (and true (= t@prime t)))))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "; tr0"
    , "(assert (elem@@sl$TRAIN t in))"
    , "(assert (not true))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/tr0/TR/WFIS/t/t@prime"
    ]

case5 :: IO String
case5 = proof_obligation path0 "train0/tr0/TR/WFIS/t/t@prime" 0

result23 :: String
result23 = unlines 
    [ "; train0/tr0/TR/leave/EN"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(declare-fun t@param () sl$TRAIN)"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (= t@param t))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not (=> (elem@@sl$TRAIN t in) (elem@@sl$TRAIN t@param in))))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/tr0/TR/leave/EN"
    ]

case23 :: IO String
case23 = proof_obligation path0 "train0/tr0/TR/leave/EN" 0

result24 :: String
result24 = unlines 
    [ "; train0/tr0/TR/leave/NEG"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(declare-fun t@param () sl$TRAIN)"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "(assert (= t@param t))"
    , "; a0"
    , "(assert (= in@prime"
    , "           (set-diff@@sl$TRAIN in (mk-set@@sl$TRAIN t@param))))"
    , "; a3"
    , "(assert (= loc@prime"
    , "           (dom-subt@@sl$TRAIN@@sl$BLK (mk-set@@sl$TRAIN t@param) loc)))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; c0"
    , "(assert (elem@@sl$TRAIN t@param in))"
    , "; grd0"
    , "(assert (and (= (apply@@sl$TRAIN@@sl$BLK loc t@param) ext)"
    , "             (elem@@sl$TRAIN t@param in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not (=> (elem@@sl$TRAIN t in)"
    , "                 (not (elem@@sl$TRAIN t in@prime)))))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/tr0/TR/leave/NEG"
    ]

case24 :: IO String
case24 = proof_obligation path0 "train0/tr0/TR/leave/NEG" 0


result12 :: String
result12 = unlines 
    [ "; train0/leave/INV/inv2"
    , "(set-option :auto-config false)"
    , "(set-option :smt.timeout 3000)"
    , "(declare-datatypes (a) ( (Maybe (Just (fromJust a)) Nothing) ))"
    , "(declare-datatypes () ( (Null null) ))"
    , "(declare-datatypes (a b) ( (Pair (pair (first a) (second b))) ))"
    , "(define-sort guarded (a) (Maybe a))"
    , "(declare-sort sl$BLK 0)"
    , "; comment: we don't need to declare the sort Bool"
    , "; comment: we don't need to declare the sort Int"
    , "(declare-sort sl$LOC 0)"
    , "; comment: we don't need to declare the sort Real"
    , "(declare-sort sl$TRAIN 0)"
    , "(define-sort pfun (a b) (Array a (Maybe b)))"
    , "(define-sort set (a) (Array a Bool))"
    , "(declare-const PLF (set sl$BLK))"
    , "(declare-const ent sl$BLK)"
    , "(declare-const ext sl$BLK)"
    , "(declare-const in (set sl$TRAIN))"
    , "(declare-const in@prime (set sl$TRAIN))"
    , "(declare-const loc (pfun sl$TRAIN sl$BLK))"
    , "(declare-const loc@prime (pfun sl$TRAIN sl$BLK))"
    , "(declare-const t sl$TRAIN)"
    , "(declare-fun apply@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               sl$TRAIN )"
    , "             sl$BLK)"
    , "(declare-fun card@@sl$BLK ( (set sl$BLK) ) Int)"
    , "(declare-fun card@@sl$LOC ( (set sl$LOC) ) Int)"
    , "(declare-fun card@@sl$TRAIN ( (set sl$TRAIN) ) Int)"
    , "(declare-fun dom@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$TRAIN))"
    , "(declare-fun dom-rest@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun dom-subt@@sl$TRAIN@@sl$BLK"
    , "             ( (set sl$TRAIN)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun empty-fun@@sl$TRAIN@@sl$BLK"
    , "             ()"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun finite@@sl$BLK ( (set sl$BLK) ) Bool)"
    , "(declare-fun finite@@sl$LOC ( (set sl$LOC) ) Bool)"
    , "(declare-fun finite@@sl$TRAIN ( (set sl$TRAIN) ) Bool)"
    , "(declare-fun injective@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             Bool)"
    , "(declare-fun mk-fun@@sl$TRAIN@@sl$BLK"
    , "             (sl$TRAIN sl$BLK)"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun mk-set@@sl$BLK (sl$BLK) (set sl$BLK))"
    , "(declare-fun mk-set@@sl$TRAIN (sl$TRAIN) (set sl$TRAIN))"
    , "(declare-fun ovl@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK)"
    , "               (pfun sl$TRAIN sl$BLK) )"
    , "             (pfun sl$TRAIN sl$BLK))"
    , "(declare-fun ran@@sl$TRAIN@@sl$BLK"
    , "             ( (pfun sl$TRAIN sl$BLK) )"
    , "             (set sl$BLK))"
    , "(define-fun all@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun all@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun all@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(define-fun compl@@sl$BLK"
    , "            ( (s1 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$LOC"
    , "            ( (s1 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun compl@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            ( (_ map not)"
    , "              s1 ))"
    , "(define-fun elem@@sl$BLK"
    , "            ( (x sl$BLK)"
    , "              (s1 (set sl$BLK)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun elem@@sl$TRAIN"
    , "            ( (x sl$TRAIN)"
    , "              (s1 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (select s1 x))"
    , "(define-fun empty-set@@sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              false ))"
    , "(define-fun empty-set@@sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              false ))"
    , "(define-fun empty-set@@sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              false ))"
    , "(define-fun set-diff@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            (set sl$BLK)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            (set sl$LOC)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun set-diff@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            (set sl$TRAIN)"
    , "            (intersect s1 ( (_ map not) s2 )))"
    , "(define-fun st-subset@@sl$BLK"
    , "            ( (s1 (set sl$BLK))"
    , "              (s2 (set sl$BLK)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$LOC"
    , "            ( (s1 (set sl$LOC))"
    , "              (s2 (set sl$LOC)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun st-subset@@sl$TRAIN"
    , "            ( (s1 (set sl$TRAIN))"
    , "              (s2 (set sl$TRAIN)) )"
    , "            Bool"
    , "            (and (subset s1 s2) (not (= s1 s2))))"
    , "(define-fun sl$BLK"
    , "            ()"
    , "            (set sl$BLK)"
    , "            ( (as const (set sl$BLK))"
    , "              true ))"
    , "(define-fun sl$LOC"
    , "            ()"
    , "            (set sl$LOC)"
    , "            ( (as const (set sl$LOC))"
    , "              true ))"
    , "(define-fun sl$TRAIN"
    , "            ()"
    , "            (set sl$TRAIN)"
    , "            ( (as const (set sl$TRAIN))"
    , "              true ))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK r) (<= 0 (card@@sl$BLK r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$BLK r)) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC r) (<= 0 (card@@sl$LOC r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$LOC r)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN r) (<= 0 (card@@sl$TRAIN r)))"
    , "                   :pattern"
    , "                   ( (<= 0 (card@@sl$TRAIN r)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 0) (= r empty-set@@sl$BLK))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$LOC)) )"
    , "                (! (= (= (card@@sl$LOC r) 0) (= r empty-set@@sl$LOC))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 0)"
    , "                      (= r empty-set@@sl$TRAIN))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (= (card@@sl$BLK (mk-set@@sl$BLK x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (= (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) 1)"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (forall ( (r (set sl$BLK)) )"
    , "                (! (= (= (card@@sl$BLK r) 1)"
    , "                      (exists ( (x sl$BLK) ) (and true (= r (mk-set@@sl$BLK x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK r) ))))"
    , "(assert (forall ( (r (set sl$TRAIN)) )"
    , "                (! (= (= (card@@sl$TRAIN r) 1)"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true (= r (mk-set@@sl$TRAIN x)))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN r) ))))"
    , "(assert (forall ( (r (set sl$BLK))"
    , "                  (r0 (set sl$BLK)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$BLK)"
    , "                       (= (card@@sl$BLK (union r r0))"
    , "                          (+ (card@@sl$BLK r) (card@@sl$BLK r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$BLK (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$LOC))"
    , "                  (r0 (set sl$LOC)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$LOC)"
    , "                       (= (card@@sl$LOC (union r r0))"
    , "                          (+ (card@@sl$LOC r) (card@@sl$LOC r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$LOC (union r r0)) ))))"
    , "(assert (forall ( (r (set sl$TRAIN))"
    , "                  (r0 (set sl$TRAIN)) )"
    , "                (! (=> (= (intersect r r0) empty-set@@sl$TRAIN)"
    , "                       (= (card@@sl$TRAIN (union r r0))"
    , "                          (+ (card@@sl$TRAIN r) (card@@sl$TRAIN r0))))"
    , "                   :pattern"
    , "                   ( (card@@sl$TRAIN (union r r0)) ))))"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$TRAIN))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK f1 empty-fun@@sl$TRAIN@@sl$BLK) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1)"
    , "                      f1)"
    , "                   :pattern"
    , "                   ( (ovl@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f2 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f2))))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2) x) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (and (elem@@sl$TRAIN x s1)"
    , "                            (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1) x) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (f2 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2))"
    , "                      (union (dom@@sl$TRAIN@@sl$BLK f1)"
    , "                             (dom@@sl$TRAIN@@sl$BLK f2)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 f2)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (intersect s1 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN)) )"
    , "                (! (= (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))"
    , "                      (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                   :pattern"
    , "                   ( (dom@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                           (= (apply@@sl$TRAIN@@sl$BLK f1 x) y))"
    , "                      (= (select f1 x) (Just y)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                     (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                     (select f1 x)"
    , "                     (Just y) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (x2 sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (= x x2))"
    , "                       (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                                   x2)"
    , "                          (apply@@sl$TRAIN@@sl$BLK f1 x2)))"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x2) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                               x)"
    , "                      y)"
    , "                   :pattern"
    , "                   ( (apply@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                                              x) ))))"
    , "(assert (= (ran@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK)"
    , "           empty-set@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1))"
    , "                      (exists ( (x sl$TRAIN) )"
    , "                              (and true"
    , "                                   (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                        (= (apply@@sl$TRAIN@@sl$BLK f1 x) y)))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK y (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (= (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y))"
    , "                      (mk-set@@sl$BLK y))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (mk-fun@@sl$TRAIN@@sl$BLK x y)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK)) )"
    , "                (! (= (injective@@sl$TRAIN@@sl$BLK f1)"
    , "                      (forall ( (x sl$TRAIN)"
    , "                                (x2 sl$TRAIN) )"
    , "                              (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                                       (elem@@sl$TRAIN x2 (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                                  (=> (= (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                         (apply@@sl$TRAIN@@sl$BLK f1 x2))"
    , "                                      (= x x2)))))"
    , "                   :pattern"
    , "                   ( (injective@@sl$TRAIN@@sl$BLK f1) ))))"
    , "(assert (injective@@sl$TRAIN@@sl$BLK empty-fun@@sl$TRAIN@@sl$BLK))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK f1)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK f1)) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x"
    , "                                       (set-diff@@sl$TRAIN (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-subt@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (s1 (set sl$TRAIN))"
    , "                  (x sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN x (intersect (dom@@sl$TRAIN@@sl$BLK f1) s1))"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                     (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)"
    , "                                   (ran@@sl$TRAIN@@sl$BLK (dom-rest@@sl$TRAIN@@sl$BLK s1 f1))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (and (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1))"
    , "                            (injective@@sl$TRAIN@@sl$BLK f1))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (set-diff@@sl$BLK (ran@@sl$TRAIN@@sl$BLK f1)"
    , "                                                   (mk-set@@sl$BLK (apply@@sl$TRAIN@@sl$BLK f1 x)))"
    , "                                 (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (f1 (pfun sl$TRAIN sl$BLK))"
    , "                  (x sl$TRAIN)"
    , "                  (y sl$BLK) )"
    , "                (! (=> (not (elem@@sl$TRAIN x (dom@@sl$TRAIN@@sl$BLK f1)))"
    , "                       (= (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y)))"
    , "                          (union (ran@@sl$TRAIN@@sl$BLK f1) (mk-set@@sl$BLK y))))"
    , "                   :pattern"
    , "                   ( (ran@@sl$TRAIN@@sl$BLK (ovl@@sl$TRAIN@@sl$BLK f1 (mk-fun@@sl$TRAIN@@sl$BLK x y))) ))))"
    , "(assert (forall ( (x sl$BLK)"
    , "                  (y sl$BLK) )"
    , "                (! (= (elem@@sl$BLK x (mk-set@@sl$BLK y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK x (mk-set@@sl$BLK y)) ))))"
    , "(assert (forall ( (x sl$TRAIN)"
    , "                  (y sl$TRAIN) )"
    , "                (! (= (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) (= x y))"
    , "                   :pattern"
    , "                   ( (elem@@sl$TRAIN x (mk-set@@sl$TRAIN y)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (finite@@sl$BLK s1)"
    , "                       (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (finite@@sl$LOC s1)"
    , "                       (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (finite@@sl$TRAIN s1)"
    , "                       (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s1) (finite@@sl$BLK s2))"
    , "                       (finite@@sl$BLK (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s1) (finite@@sl$LOC s2))"
    , "                       (finite@@sl$LOC (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s1) (finite@@sl$TRAIN s2))"
    , "                       (finite@@sl$TRAIN (union s1 s2)))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (union s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$BLK))"
    , "                  (s2 (set sl$BLK)) )"
    , "                (! (=> (and (finite@@sl$BLK s2) (not (finite@@sl$BLK s1)))"
    , "                       (not (finite@@sl$BLK (set-diff@@sl$BLK s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (set-diff@@sl$BLK s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$LOC))"
    , "                  (s2 (set sl$LOC)) )"
    , "                (! (=> (and (finite@@sl$LOC s2) (not (finite@@sl$LOC s1)))"
    , "                       (not (finite@@sl$LOC (set-diff@@sl$LOC s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$LOC (set-diff@@sl$LOC s1 s2)) ))))"
    , "(assert (forall ( (s1 (set sl$TRAIN))"
    , "                  (s2 (set sl$TRAIN)) )"
    , "                (! (=> (and (finite@@sl$TRAIN s2) (not (finite@@sl$TRAIN s1)))"
    , "                       (not (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2))))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (set-diff@@sl$TRAIN s1 s2)) ))))"
    , "(assert (forall ( (x sl$BLK) )"
    , "                (! (finite@@sl$BLK (mk-set@@sl$BLK x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$BLK (mk-set@@sl$BLK x)) ))))"
    , "(assert (forall ( (x sl$TRAIN) )"
    , "                (! (finite@@sl$TRAIN (mk-set@@sl$TRAIN x))"
    , "                   :pattern"
    , "                   ( (finite@@sl$TRAIN (mk-set@@sl$TRAIN x)) ))))"
    , "(assert (finite@@sl$BLK empty-set@@sl$BLK))"
    , "(assert (finite@@sl$LOC empty-set@@sl$LOC))"
    , "(assert (finite@@sl$TRAIN empty-set@@sl$TRAIN))"
    , "; a0"
    , "(assert (= in@prime"
    , "           (set-diff@@sl$TRAIN in (mk-set@@sl$TRAIN t))))"
    , "; a3"
    , "(assert (= loc@prime"
    , "           (dom-subt@@sl$TRAIN@@sl$BLK (mk-set@@sl$TRAIN t) loc)))"
    , "; asm2"
    , "(assert (and (not (= ent ext))"
    , "             (not (elem@@sl$BLK ent PLF))"
    , "             (not (elem@@sl$BLK ext PLF))))"
    , "; asm3"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ext))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ent) PLF)) ))))"
    , "; asm4"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (not (= p ent))"
    , "                      (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p (union (mk-set@@sl$BLK ext) PLF)) ))))"
    , "; asm5"
    , "(assert (forall ( (p sl$BLK) )"
    , "                (! (= (or (= p ent) (= p ext))"
    , "                      (not (elem@@sl$BLK p PLF)))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK p PLF) ))))"
    , "; axm0"
    , "(assert (= sl$BLK"
    , "           (union (union (mk-set@@sl$BLK ent) (mk-set@@sl$BLK ext))"
    , "                  PLF)))"
    , "; c0"
    , "(assert (elem@@sl$TRAIN t in))"
    , "; grd0"
    , "(assert (and (= (apply@@sl$TRAIN@@sl$BLK loc t) ext)"
    , "             (elem@@sl$TRAIN t in)))"
    , "; inv1"
    , "(assert (forall ( (t sl$TRAIN) )"
    , "                (! (=> (elem@@sl$TRAIN t in)"
    , "                       (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK))"
    , "                   :pattern"
    , "                   ( (elem@@sl$BLK (apply@@sl$TRAIN@@sl$BLK loc t) sl$BLK) ))))"
    , "; inv2"
    , "(assert (= (dom@@sl$TRAIN@@sl$BLK loc) in))"
    , "(assert (not (= (dom@@sl$TRAIN@@sl$BLK loc@prime) in@prime)))"
    , "(check-sat-using (or-else (then qe smt)"
    , "                          (then simplify smt)"
    , "                          (then skip smt)"
    , "                          (then (using-params simplify :expand-power true) smt)))"
    , "; train0/leave/INV/inv2"
    ]

case12 :: IO String
case12 = raw_proof_obligation path0 "train0/leave/INV/inv2" 0

    --------------------
    -- Error handling --
    --------------------
result7 :: String
result7 = unlines 
    [ "error 54:4:"
    , "    unrecognized term: t" 
    ]

path7 :: FilePath
path7 = [path|Tests/train-station-err0.tex|]

case7 :: IO String
case7 = find_errors path7

result8 :: String
result8 = unlines 
    [ "error 43:1:"
    , "    event 'leave' is undeclared"
    ]

path8 :: FilePath
path8 = [path|Tests/train-station-err1.tex|]

case8 :: IO String
case8 = find_errors path8

result9 :: String
result9 = unlines
    [ "error 52:1:"
    , "    event 'leave' is undeclared" 
    ]

path9 :: FilePath
path9 = [path|Tests/train-station-err2.tex|]

case9 :: IO String
case9 = find_errors path9

result10 :: String
result10 = unlines 
    [ "error 56:1:"
    , "    event 'leave' is undeclared" 
    ]

path10 :: FilePath
path10 = [path|Tests/train-station-err3.tex|]

case10 :: IO String
case10 = find_errors path10

result11 :: String
result11 = unlines 
    [ "error 60:1:"
    , "    event 'leave' is undeclared" 
    ]

path11 :: FilePath
path11 = [path|Tests/train-station-err4.tex|]

case11 :: IO String
case11 = find_errors path11

path13 :: FilePath
path13 = [path|Tests/train-station-err5.tex|]

result13 :: String
result13 = unlines
    [ "error 176:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 178:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 180:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 182:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 186:34:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 251:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 253:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 256:7:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 261:6:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 264:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 267:5:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 269:6:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 272:6:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    , ""
    , "error 274:6:"
    , "    unrecognized term: t0"
    , "Perhaps you meant:"
    , "t (variable)"
    ]

case13 :: IO String
case13 = find_errors path13


path14 :: FilePath
path14 = [path|Tests/train-station-err6.tex|]

result14 :: String
result14 = unlines
    [ "  o  train0/INIT/INV/inv1"
    , "  o  train0/INIT/INV/inv2"
    , "  o  train0/INV/WD"
    , "  o  train0/SKIP/CO/co0"
    , "  o  train0/SKIP/CO/co1"
    , "  o  train0/co0/CO/WD"
    , "  o  train0/co1/CO/WD"
    , "  o  train0/enter/CO/co0/case 1/goal"
    , "  o  train0/enter/CO/co0/case 1/hypotheses"
    , "  o  train0/enter/CO/co0/case 1/relation"
    , "  o  train0/enter/CO/co0/case 1/step 1"
    , "  o  train0/enter/CO/co0/case 1/step 2"
    , " xxx train0/enter/CO/co0/completeness"
    , "  o  train0/enter/CO/co1"
    , "  o  train0/enter/FIS/in@prime"
    , "  o  train0/enter/FIS/loc@prime"
    , "  o  train0/enter/INV/inv1"
    , "  o  train0/enter/INV/inv2/goal"
    , "  o  train0/enter/INV/inv2/hypotheses"
    , "  o  train0/enter/INV/inv2/relation"
    , "  o  train0/enter/INV/inv2/step 1"
    , "  o  train0/enter/INV/inv2/step 2"
    , "  o  train0/enter/INV/inv2/step 3"
    , "  o  train0/enter/INV/inv2/step 4"
    , "  o  train0/enter/INV/inv2/step 5"
    , "  o  train0/enter/SAF/s0"
    , "  o  train0/enter/SAF/s1"
    , "  o  train0/enter/SCH/grd1"
    , "  o  train0/leave/CO/co0/goal"
    , "  o  train0/leave/CO/co0/hypotheses"
    , "  o  train0/leave/CO/co0/relation"
    , "  o  train0/leave/CO/co0/step 1"
    , "  o  train0/leave/CO/co0/step 2"
    , "  o  train0/leave/CO/co0/step 3"
    , "  o  train0/leave/CO/co0/step 4"
    , "  o  train0/leave/CO/co1/goal"
    , "  o  train0/leave/CO/co1/hypotheses"
    , "  o  train0/leave/CO/co1/relation"
    , "  o  train0/leave/CO/co1/step 1"
    , "  o  train0/leave/CO/co1/step 2"
    , "  o  train0/leave/CO/co1/step 3"
    , "  o  train0/leave/CO/co1/step 4"
    , "  o  train0/leave/CO/co1/step 5"
    , "  o  train0/leave/CO/co1/step 6"
    , "  o  train0/leave/CO/co1/step 7"
    , "  o  train0/leave/CO/co1/step 8"
    , "  o  train0/leave/FIS/in@prime"
    , "  o  train0/leave/FIS/loc@prime"
    , "  o  train0/leave/INV/inv1"
    , "  o  train0/leave/INV/inv2/goal"
    , "  o  train0/leave/INV/inv2/hypotheses"
    , "  o  train0/leave/INV/inv2/relation"
    , "  o  train0/leave/INV/inv2/step 1"
    , "  o  train0/leave/INV/inv2/step 2"
    , "  o  train0/leave/INV/inv2/step 3"
    , "  o  train0/leave/INV/inv2/step 4"
    , "  o  train0/leave/SAF/s0"
    , "  o  train0/leave/SAF/s1"
    , " xxx train0/leave/SCH/grd0"
    , "  o  train0/leave/WD/GRD"
    , "  o  train0/s0/SAF/WD/rhs"
    , "  o  train0/s1/SAF/WD/lhs"
    , "  o  train0/s1/SAF/WD/rhs"
    , "  o  train0/tr0/TR/WFIS/t/t@prime"
    , "  o  train0/tr0/TR/leave/EN"
    , "  o  train0/tr0/TR/leave/NEG"
    , "passed 64 / 66"
    ]

case14 :: IO (String, Map Label Sequent)
case14 = verify path14 0
    
path15 :: FilePath
path15 = [path|Tests/train-station-err7.tex|]

result15 :: String
result15 = unlines
    [ "  o  train0/INIT/INV/inv1"
    , "  o  train0/INIT/INV/inv2"
    , "  o  train0/INV/WD"
    , "  o  train0/SKIP/CO/co0"
    , "  o  train0/SKIP/CO/co1"
    , "  o  train0/co0/CO/WD"
    , "  o  train0/co1/CO/WD"
    , "  o  train0/enter/CO/co0/case 1/goal"
    , "  o  train0/enter/CO/co0/case 1/hypotheses"
    , "  o  train0/enter/CO/co0/case 1/relation"
    , "  o  train0/enter/CO/co0/case 1/step 1"
    , "  o  train0/enter/CO/co0/case 1/step 2"
    , "  o  train0/enter/CO/co0/case 2/goal"
    , "  o  train0/enter/CO/co0/case 2/hypotheses"
    , "  o  train0/enter/CO/co0/case 2/relation"
    , "  o  train0/enter/CO/co0/case 2/step 1"
    , "  o  train0/enter/CO/co0/case 2/step 2"
    , "  o  train0/enter/CO/co0/case 2/step 3"
    , "  o  train0/enter/CO/co0/case 2/step 4"
    , "  o  train0/enter/CO/co0/completeness"
    , "  o  train0/enter/CO/co1"
    , "  o  train0/enter/FIS/in@prime"
    , "  o  train0/enter/FIS/loc@prime"
    , "  o  train0/enter/INV/inv1"
    , "  o  train0/enter/INV/inv2/goal"
    , "  o  train0/enter/INV/inv2/hypotheses"
    , "  o  train0/enter/INV/inv2/relation"
    , "  o  train0/enter/INV/inv2/step 1"
    , "  o  train0/enter/INV/inv2/step 2"
    , "  o  train0/enter/INV/inv2/step 3"
    , "  o  train0/enter/INV/inv2/step 4"
    , "  o  train0/enter/INV/inv2/step 5"
    , "  o  train0/enter/SAF/s0"
    , "  o  train0/enter/SAF/s1"
    , "  o  train0/enter/SCH/grd1"
    , "  o  train0/leave/CO/co0/goal"
    , "  o  train0/leave/CO/co0/hypotheses"
    , " xxx train0/leave/CO/co0/new assumption"
    , "  o  train0/leave/CO/co0/relation"
    , "  o  train0/leave/CO/co0/step 1"
    , " xxx train0/leave/CO/co0/step 2"
    , "  o  train0/leave/CO/co1/goal"
    , "  o  train0/leave/CO/co1/hypotheses"
    , "  o  train0/leave/CO/co1/relation"
    , "  o  train0/leave/CO/co1/step 1"
    , "  o  train0/leave/CO/co1/step 2"
    , "  o  train0/leave/CO/co1/step 3"
    , "  o  train0/leave/CO/co1/step 4"
    , "  o  train0/leave/CO/co1/step 5"
    , "  o  train0/leave/CO/co1/step 6"
    , "  o  train0/leave/CO/co1/step 7"
    , "  o  train0/leave/CO/co1/step 8"
    , "  o  train0/leave/FIS/in@prime"
    , "  o  train0/leave/FIS/loc@prime"
    , "  o  train0/leave/INV/inv1"
    , "  o  train0/leave/INV/inv2/goal"
    , "  o  train0/leave/INV/inv2/hypotheses"
    , "  o  train0/leave/INV/inv2/relation"
    , "  o  train0/leave/INV/inv2/step 1"
    , "  o  train0/leave/INV/inv2/step 2"
    , "  o  train0/leave/INV/inv2/step 3"
    , "  o  train0/leave/INV/inv2/step 4"
    , "  o  train0/leave/SAF/s0"
    , "  o  train0/leave/SAF/s1"
    , " xxx train0/leave/SCH/grd0"
    , "  o  train0/leave/WD/GRD"
    , "  o  train0/s0/SAF/WD/rhs"
    , "  o  train0/s1/SAF/WD/lhs"
    , "  o  train0/s1/SAF/WD/rhs"
    , "  o  train0/tr0/TR/WFIS/t/t@prime"
    , "  o  train0/tr0/TR/leave/EN"
    , "  o  train0/tr0/TR/leave/NEG"
    , "passed 69 / 72"
    ]

case15 :: IO (String, Map Label Sequent)
case15 = verify path15 0

path16 :: FilePath
path16 = [path|Tests/train-station-t2.tex|]

result16 :: String
result16 = unlines 
    [ "  o  train0/INIT/INV/inv1"
    , "  o  train0/INIT/INV/inv2"
    , "  o  train0/INV/WD"
    , "  o  train0/SKIP/CO/co0"
    , "  o  train0/SKIP/CO/co1"
    , "  o  train0/co0/CO/WD"
    , "  o  train0/co1/CO/WD"
    , "  o  train0/enter/CO/co0/case 1/goal"
    , "  o  train0/enter/CO/co0/case 1/hypotheses"
    , "  o  train0/enter/CO/co0/case 1/relation"
    , "  o  train0/enter/CO/co0/case 1/step 1"
    , "  o  train0/enter/CO/co0/case 1/step 2"
    , "  o  train0/enter/CO/co0/case 2/goal"
    , "  o  train0/enter/CO/co0/case 2/hypotheses"
    , "  o  train0/enter/CO/co0/case 2/relation"
    , "  o  train0/enter/CO/co0/case 2/step 1"
    , "  o  train0/enter/CO/co0/case 2/step 2"
    , "  o  train0/enter/CO/co0/case 2/step 3"
    , "  o  train0/enter/CO/co0/case 2/step 4"
    , "  o  train0/enter/CO/co0/completeness"
    , "  o  train0/enter/CO/co1/completeness"
    , "  o  train0/enter/CO/co1/new assumption"
    , "  o  train0/enter/CO/co1/part 1/goal"
    , "  o  train0/enter/CO/co1/part 1/hypotheses"
    , "  o  train0/enter/CO/co1/part 1/relation"
    , "  o  train0/enter/CO/co1/part 1/step 1"
    , "  o  train0/enter/CO/co1/part 1/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 1/goal"
    , "  o  train0/enter/CO/co1/part 2/case 1/hypotheses"
    , "  o  train0/enter/CO/co1/part 2/case 1/relation"
    , "  o  train0/enter/CO/co1/part 2/case 1/step 1"
    , "  o  train0/enter/CO/co1/part 2/case 1/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 2/goal"
    , "  o  train0/enter/CO/co1/part 2/case 2/hypotheses"
    , "  o  train0/enter/CO/co1/part 2/case 2/relation"
    , "  o  train0/enter/CO/co1/part 2/case 2/step 1"
    , "  o  train0/enter/CO/co1/part 2/case 2/step 2"
    , "  o  train0/enter/CO/co1/part 2/case 2/step 3"
    , "  o  train0/enter/CO/co1/part 2/completeness"
    , "  o  train0/enter/FIS/in@prime"
    , "  o  train0/enter/FIS/loc@prime"
    , "  o  train0/enter/INV/inv1"
    , "  o  train0/enter/INV/inv2/goal"
    , "  o  train0/enter/INV/inv2/hypotheses"
    , "  o  train0/enter/INV/inv2/relation"
    , "  o  train0/enter/INV/inv2/step 1"
    , "  o  train0/enter/INV/inv2/step 2"
    , "  o  train0/enter/INV/inv2/step 3"
    , "  o  train0/enter/INV/inv2/step 4"
    , "  o  train0/enter/INV/inv2/step 5"
    , "  o  train0/enter/SAF/s0"
    , "  o  train0/enter/SAF/s1"
    , "  o  train0/enter/SCH/grd1"
    , "  o  train0/leave/CO/co0/goal"
    , "  o  train0/leave/CO/co0/hypotheses"
    , "  o  train0/leave/CO/co0/relation"
    , "  o  train0/leave/CO/co0/step 1"
    , "  o  train0/leave/CO/co0/step 2"
    , "  o  train0/leave/CO/co0/step 3"
    , "  o  train0/leave/CO/co0/step 4"
    , "  o  train0/leave/CO/co1/goal"
    , "  o  train0/leave/CO/co1/hypotheses"
    , "  o  train0/leave/CO/co1/relation"
    , "  o  train0/leave/CO/co1/step 1"
    , "  o  train0/leave/CO/co1/step 2"
    , "  o  train0/leave/CO/co1/step 3"
    , "  o  train0/leave/CO/co1/step 4"
    , "  o  train0/leave/CO/co1/step 5"
    , "  o  train0/leave/CO/co1/step 6"
    , "  o  train0/leave/CO/co1/step 7"
    , "  o  train0/leave/CO/co1/step 8"
    , "  o  train0/leave/FIS/in@prime"
    , "  o  train0/leave/FIS/loc@prime"
    , "  o  train0/leave/INV/inv1"
    , "  o  train0/leave/INV/inv2/goal"
    , "  o  train0/leave/INV/inv2/hypotheses"
    , "  o  train0/leave/INV/inv2/relation"
    , "  o  train0/leave/INV/inv2/step 1"
    , "  o  train0/leave/INV/inv2/step 2"
    , "  o  train0/leave/INV/inv2/step 3"
    , "  o  train0/leave/INV/inv2/step 4"
    , "  o  train0/leave/SAF/s0"
    , "  o  train0/leave/SAF/s1"
    , " xxx train0/leave/SCH/grd0"
    , "  o  train0/leave/WD/GRD"
    , "  o  train0/s0/SAF/WD/rhs"
    , "  o  train0/s1/SAF/WD/lhs"
    , "  o  train0/s1/SAF/WD/rhs"
    , "  o  train0/tr0/TR/WFIS/t/t@prime"
    , "  o  train0/tr0/TR/leave/EN"
    , "  o  train0/tr0/TR/leave/NEG"
    , "passed 90 / 91"
    ]

case16 :: IO (String, Map Label Sequent)
case16 = verify path16 0

path17 :: FilePath
path17 = [path|Tests/train-station-err8.tex|]

result17 :: String
result17 = unlines 
        [  "error 75:4:\n    type of empty-fun is ill-defined: \\pfun [\\TRAIN,_a]"
        ,  ""
        ,  "error 75:4:\n    type of empty-fun is ill-defined: \\pfun [\\TRAIN,_b]"
        ,  ""
        ,  "error 77:3:\n    type of empty-fun is ill-defined: \\pfun [\\TRAIN,_a]"
        ]

case17 :: IO String
case17 = find_errors path17

path22 :: FilePath
path22 = [path|Tests/train-station-err11.tex|]

result22 :: String
result22 = unlines 
        [  "error 48:1:\n    event(s) leave have indices and require witnesses"
        ]

case22 :: IO String
case22 = find_errors path22
        
path18 :: FilePath
path18 = [path|Tests/train-station-err9.tex|]

result18 :: String
result18 = unlines 
        [  "error 68:3:\n    expression has type incompatible with its expected type:"
        ,  "  expression: (dom loc)"
        ,  "  actual type: \\set [\\TRAIN]"
        ,  "  expected type: \\Bool "
        ,  ""
        ,  "error 73:3:\n    expression has type incompatible with its expected type:"
        ,  "  expression: (union in (mk-set t))"
        ,  "  actual type: \\set [\\TRAIN]"
        ,  "  expected type: \\Bool "
        ,  ""
        ,  "error 118:3:\n    expression has type incompatible with its expected type:"
        ,  "  expression: t"
        ,  "  actual type: \\TRAIN"
        ,  "  expected type: \\Bool "
        ,  ""
        ,  "error 123:3:\n    expression has type incompatible with its expected type:"
        ,  "  expression: empty-set"
        ,  "  actual type: \\set [_a]"
        ,  "  expected type: \\Bool "
        ]

case18 :: IO String
case18 = find_errors path18

path21 :: FilePath
path21 = [path|Tests/train-station-err10.tex|]

case21 :: IO String
case21 = find_errors path21

result21 :: String
result21 = unlines
    [ "Theory imported multiple times"
    , "error 130:1:"
    , "\tsets"
    , ""
    , "error 131:1:"
    , "\tsets"
    , ""
    , "error 132:1:"
    , "\tsets"
    , ""
    ]
