anaNodeQuery :: [String] -> NodeIdOrName -> [String] -> [String]
  -> [QueryPair] -> Either String QueryKind
anaNodeQuery ans i moreTheorems incls pss =
  let pps = foldr (\ l -> case l of
                (x, Just y) -> ((x, y) :)
                _ -> id) [] pss
      incl = lookup "include" pps
      trans = fmap decodeQuery $ lookup "translation" pps
      prover = lookup "prover" pps
      theorems = map unEsc moreTheorems
          ++ case lookup "theorems" pps of
        Nothing -> []
        Just str -> map unEsc $ splitOn ' ' $ decodeQuery str
      timeLimit = maybe Nothing readMaybe $ lookup "timeout" pps
      pp = ProveNode $ ProveCmd GlProofs (not (null incls) || case incl of
        Nothing -> True
        Just str -> map toLower str `notElem` ["f", "false"])
        prover trans timeLimit theorems False
      noPP = null incls && null pps
      noIncl = null incls && isNothing incl && isNothing timeLimit
      cmds = map (\ a -> (showNodeCmd a, a)) nodeCmds
  in case ans of
       [] -> Right $ NodeQuery i
         $ if noPP then NcCmd minBound else pp
       [cmd] -> case cmd of
         "prove" -> Right $ NodeQuery i pp
         "provers" | noIncl && isNothing prover ->
            Right $ NodeQuery i $ NcProvers GlProofs trans
         "translations" | noIncl && isNothing trans ->
            Right $ NodeQuery i $ NcTranslations prover
         _ -> case lookup cmd cmds of
           Just nc | noPP -> Right $ NodeQuery i $ NcCmd nc
           _ -> Left $ "unknown node command '" ++ cmd ++ "' "
                ++ shows incls " " ++ show pss
       _ -> Left $ "non-unique node command " ++ show ans
anaNodeQuery :: [String] -> NodeIdOrName -> [String] -> [String]
  -> [QueryPair] -> Either String QueryKind
anaNodeQuery ans i moreTheorems incls pss =
  let pps = foldr (\ l -> case l of
                (x, Just y) -> ((x, y) :)
                _ -> id) [] pss
      incl = lookup "include" pps
      trans = fmap decodeQuery $ lookup "translation" pps
      prover = lookup "prover" pps
      theorems = map unEsc moreTheorems
          ++ case lookup "theorems" pps of
        Nothing -> []
        Just str -> map unEsc $ splitOn ' ' $ decodeQuery str
      timeLimit = maybe Nothing readMaybe $ lookup "timeout" pps
      pp = ProveNode $ ProveCmd GlProofs (not (null incls) || case incl of
        Nothing -> True
        Just str -> map toLower str `notElem` ["f", "false"])
        prover trans timeLimit theorems False
      noPP = null incls && null pps
      noIncl = null incls && isNothing incl && isNothing timeLimit
      cmds = map (\ a -> (showNodeCmd a, a)) nodeCmds
  in case ans of
       [] -> Right $ NodeQuery i
         $ if noPP then NcCmd minBound else pp
       [cmd] -> case cmd of
         "prove" -> Right $ NodeQuery i pp
         "provers" | noIncl && isNothing prover ->
            Right $ NodeQuery i $ NcProvers GlProofs trans
         "translations" | noIncl && isNothing trans ->
            Right $ NodeQuery i $ NcTranslations prover
         _ -> case lookup cmd cmds of
           Just nc | noPP -> Right $ NodeQuery i $ NcCmd nc
           _ -> Left $ "unknown node command '" ++ cmd ++ "' "
                ++ shows incls " " ++ show pss
       _ -> Left $ "non-unique node command " ++ show ans
anaNodeQuery ans i moreTheorems incls pss =
  let pps = foldr (\ l -> case l of
                (x, Just y) -> ((x, y) :)
                _ -> id) [] pss
      incl = lookup "include" pps
      trans = fmap decodeQuery $ lookup "translation" pps
      prover = lookup "prover" pps
      theorems = map unEsc moreTheorems
          ++ case lookup "theorems" pps of
        Nothing -> []
        Just str -> map unEsc $ splitOn ' ' $ decodeQuery str
      timeLimit = maybe Nothing readMaybe $ lookup "timeout" pps
      pp = ProveNode $ ProveCmd GlProofs (not (null incls) || case incl of
        Nothing -> True
        Just str -> map toLower str `notElem` ["f", "false"])
        prover trans timeLimit theorems False
      noPP = null incls && null pps
      noIncl = null incls && isNothing incl && isNothing timeLimit
      cmds = map (\ a -> (showNodeCmd a, a)) nodeCmds
  in case ans of
       [] -> Right $ NodeQuery i
         $ if noPP then NcCmd minBound else pp
       [cmd] -> case cmd of
         "prove" -> Right $ NodeQuery i pp
         "provers" | noIncl && isNothing prover ->
            Right $ NodeQuery i $ NcProvers GlProofs trans
         "translations" | noIncl && isNothing trans ->
            Right $ NodeQuery i $ NcTranslations prover
         _ -> case lookup cmd cmds of
           Just nc | noPP -> Right $ NodeQuery i $ NcCmd nc
           _ -> Left $ "unknown node command '" ++ cmd ++ "' "
                ++ shows incls " " ++ show pss
       _ -> Left $ "non-unique node command " ++ show ans