generator :: Model Symbolic -> Maybe (Gen (Command Symbolic))
generator (Model m) = Just $ oneof $ [
    NewBook      New     <$> newIsbn <*> stringGen <*> stringGen
  , AddCopy      Invalid <$> newIsbn
  , Borrow       Invalid <$> newIsbn
  , Return       Invalid <$> newIsbn
  , FindByIsbn   Invalid <$> newIsbn
  , FindByTitle  Invalid <$> searchStringGen
  , FindByAuthor Invalid <$> searchStringGen
  ] ++ if null m then [] else [
    NewBook      Exist   <$> existIsbn <*> stringGen <*> stringGen
  , AddCopy      Exist   <$> existIsbn
  , Borrow       Avail   <$> existIsbn
  , Borrow       Unavail <$> existIsbn
  , Return       Taken   <$> existIsbn
  , Return       Full    <$> existIsbn
  , FindByIsbn   Exist   <$> existIsbn
  , FindByTitle  Exist   <$> genTitle
  , FindByAuthor Exist   <$> genAuthor
  ]
  where
    newIsbn = arbitrary `suchThat` \x -> x `notElem` domain m
    existIsbn = elements $ domain m
    genTitle  = elements $ (title  <$> codomain m) >>= infixes
    genAuthor = elements $ (author <$> codomain m) >>= infixes
generator :: Model Symbolic -> Maybe (Gen (Command Symbolic))
generator (Model m) = Just $ oneof $ [
    NewBook      New     <$> newIsbn <*> stringGen <*> stringGen
  , AddCopy      Invalid <$> newIsbn
  , Borrow       Invalid <$> newIsbn
  , Return       Invalid <$> newIsbn
  , FindByIsbn   Invalid <$> newIsbn
  , FindByTitle  Invalid <$> searchStringGen
  , FindByAuthor Invalid <$> searchStringGen
  ] ++ if null m then [] else [
    NewBook      Exist   <$> existIsbn <*> stringGen <*> stringGen
  , AddCopy      Exist   <$> existIsbn
  , Borrow       Avail   <$> existIsbn
  , Borrow       Unavail <$> existIsbn
  , Return       Taken   <$> existIsbn
  , Return       Full    <$> existIsbn
  , FindByIsbn   Exist   <$> existIsbn
  , FindByTitle  Exist   <$> genTitle
  , FindByAuthor Exist   <$> genAuthor
  ]
  where
    newIsbn = arbitrary `suchThat` \x -> x `notElem` domain m
    existIsbn = elements $ domain m
    genTitle  = elements $ (title  <$> codomain m) >>= infixes
    genAuthor = elements $ (author <$> codomain m) >>= infixes
generator (Model m) = Just $ oneof $ [
    NewBook      New     <$> newIsbn <*> stringGen <*> stringGen
  , AddCopy      Invalid <$> newIsbn
  , Borrow       Invalid <$> newIsbn
  , Return       Invalid <$> newIsbn
  , FindByIsbn   Invalid <$> newIsbn
  , FindByTitle  Invalid <$> searchStringGen
  , FindByAuthor Invalid <$> searchStringGen
  ] ++ if null m then [] else [
    NewBook      Exist   <$> existIsbn <*> stringGen <*> stringGen
  , AddCopy      Exist   <$> existIsbn
  , Borrow       Avail   <$> existIsbn
  , Borrow       Unavail <$> existIsbn
  , Return       Taken   <$> existIsbn
  , Return       Full    <$> existIsbn
  , FindByIsbn   Exist   <$> existIsbn
  , FindByTitle  Exist   <$> genTitle
  , FindByAuthor Exist   <$> genAuthor
  ]
  where
    newIsbn = arbitrary `suchThat` \x -> x `notElem` domain m
    existIsbn = elements $ domain m
    genTitle  = elements $ (title  <$> codomain m) >>= infixes
    genAuthor = elements $ (author <$> codomain m) >>= infixes