printFormula :: FORMULA -> Doc
printFormula frm =
  let ppf p f = (if p f then id else parens) $ printFormula f
      isJunctForm f = case f of
        Implication {} -> False
        Equivalence {} -> False
        ForAll {} -> False
        Exists {} -> False
        _ -> True
  in case frm of
  FalseAtom _ -> text falseS
  TrueAtom _ -> text trueS
  Predication x -> pretty x
  Negation f _ -> notDoc <+> ppf isPrimForm f
  Conjunction xs _ -> sepByArbitrary andDoc $ map (ppf isPrimForm) xs
  Disjunction xs _ -> sepByArbitrary orDoc $ map (ppf isPrimForm) xs
  Implication x y _ -> ppf isJunctForm x <+> implies <+> ppf isJunctForm y
  Equivalence x y _ -> ppf isJunctForm x <+> equiv <+> ppf isJunctForm y
  ForAll xs y _ -> forallDoc <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y
  Exists xs y _ -> exists <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y
printFormula :: FORMULA -> Doc
printFormula frm =
  let ppf p f = (if p f then id else parens) $ printFormula f
      isJunctForm f = case f of
        Implication {} -> False
        Equivalence {} -> False
        ForAll {} -> False
        Exists {} -> False
        _ -> True
  in case frm of
  FalseAtom _ -> text falseS
  TrueAtom _ -> text trueS
  Predication x -> pretty x
  Negation f _ -> notDoc <+> ppf isPrimForm f
  Conjunction xs _ -> sepByArbitrary andDoc $ map (ppf isPrimForm) xs
  Disjunction xs _ -> sepByArbitrary orDoc $ map (ppf isPrimForm) xs
  Implication x y _ -> ppf isJunctForm x <+> implies <+> ppf isJunctForm y
  Equivalence x y _ -> ppf isJunctForm x <+> equiv <+> ppf isJunctForm y
  ForAll xs y _ -> forallDoc <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y
  Exists xs y _ -> exists <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y
printFormula frm =
  let ppf p f = (if p f then id else parens) $ printFormula f
      isJunctForm f = case f of
        Implication {} -> False
        Equivalence {} -> False
        ForAll {} -> False
        Exists {} -> False
        _ -> True
  in case frm of
  FalseAtom _ -> text falseS
  TrueAtom _ -> text trueS
  Predication x -> pretty x
  Negation f _ -> notDoc <+> ppf isPrimForm f
  Conjunction xs _ -> sepByArbitrary andDoc $ map (ppf isPrimForm) xs
  Disjunction xs _ -> sepByArbitrary orDoc $ map (ppf isPrimForm) xs
  Implication x y _ -> ppf isJunctForm x <+> implies <+> ppf isJunctForm y
  Equivalence x y _ -> ppf isJunctForm x <+> equiv <+> ppf isJunctForm y
  ForAll xs y _ -> forallDoc <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y
  Exists xs y _ -> exists <+> sepByArbitrary comma (map pretty xs)
                     <+> space
                     <+> ppf isJunctForm y