convertProp :: M -> Formula
convertProp m =
  case m of
  M [] (R (RConst "top") [])            -> Top
  M [] (R (RConst "bot") [])            -> Bot
  M [] (R (RConst "\\/") [m1, m2])      -> Disj (convertProp m1) (convertProp m2)
  M [] (R (RConst "/\\") [m1, m2])      -> Conj (convertProp m1) (convertProp m2)
  M [] (R (RConst "=>") [m1, m2])       -> Imp (convertProp m1) (convertProp m2)
  M [] (R (RConst "~") [m1])            -> Neg (convertProp m1)
  M [] (R (RConst "==") [m1, m2])       -> Eq (convertTerm m1) (convertTerm m2)
  M [] (R (RConst "all")
           [M [(mx, _, _)] r])          -> All (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RConst "exi")
           [M [(mx, _, _)] r])          -> Exi (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RVar p (A bindings _)) args) ->
    Pred p (zipWith
             convertObj
             (map (bindTy . convertHypothesis) bindings)
             args)
  _ -> error $ concat ["Malformed proposition: ", show m]
convertProp :: M -> Formula
convertProp m =
  case m of
  M [] (R (RConst "top") [])            -> Top
  M [] (R (RConst "bot") [])            -> Bot
  M [] (R (RConst "\\/") [m1, m2])      -> Disj (convertProp m1) (convertProp m2)
  M [] (R (RConst "/\\") [m1, m2])      -> Conj (convertProp m1) (convertProp m2)
  M [] (R (RConst "=>") [m1, m2])       -> Imp (convertProp m1) (convertProp m2)
  M [] (R (RConst "~") [m1])            -> Neg (convertProp m1)
  M [] (R (RConst "==") [m1, m2])       -> Eq (convertTerm m1) (convertTerm m2)
  M [] (R (RConst "all")
           [M [(mx, _, _)] r])          -> All (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RConst "exi")
           [M [(mx, _, _)] r])          -> Exi (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RVar p (A bindings _)) args) ->
    Pred p (zipWith
             convertObj
             (map (bindTy . convertHypothesis) bindings)
             args)
  _ -> error $ concat ["Malformed proposition: ", show m]
convertProp m =
  case m of
  M [] (R (RConst "top") [])            -> Top
  M [] (R (RConst "bot") [])            -> Bot
  M [] (R (RConst "\\/") [m1, m2])      -> Disj (convertProp m1) (convertProp m2)
  M [] (R (RConst "/\\") [m1, m2])      -> Conj (convertProp m1) (convertProp m2)
  M [] (R (RConst "=>") [m1, m2])       -> Imp (convertProp m1) (convertProp m2)
  M [] (R (RConst "~") [m1])            -> Neg (convertProp m1)
  M [] (R (RConst "==") [m1, m2])       -> Eq (convertTerm m1) (convertTerm m2)
  M [] (R (RConst "all")
           [M [(mx, _, _)] r])          -> All (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RConst "exi")
           [M [(mx, _, _)] r])          -> Exi (maybe "_" id mx)
                                               (convertProp (M [] r))
  M [] (R (RVar p (A bindings _)) args) ->
    Pred p (zipWith
             convertObj
             (map (bindTy . convertHypothesis) bindings)
             args)
  _ -> error $ concat ["Malformed proposition: ", show m]