isValidFor :: Program -> [String] -> Bool
Program x e `isValidFor` ops
  | "tfold" `elem` ops =
      case e of
        Fold (Var x') (Const Zero) x'' y e' -> x == x' && x == x'' && op e' == ops'
        _ -> False
  | otherwise = op e == ops'
  where
    ops' = Set.fromList ops `Set.difference` Set.fromList ["tfold", "bonus"]

{--------------------------------------------------------------------
  Pretty Printing
--------------------------------------------------------------------}
isValidFor :: Program -> [String] -> Bool
Program x e `isValidFor` ops
  | "tfold" `elem` ops =
      case e of
        Fold (Var x') (Const Zero) x'' y e' -> x == x' && x == x'' && op e' == ops'
        _ -> False
  | otherwise = op e == ops'
  where
    ops' = Set.fromList ops `Set.difference` Set.fromList ["tfold", "bonus"]

{--------------------------------------------------------------------
  Pretty Printing
--------------------------------------------------------------------}
Program x e `isValidFor` ops
  | "tfold" `elem` ops =
      case e of
        Fold (Var x') (Const Zero) x'' y e' -> x == x' && x == x'' && op e' == ops'
        _ -> False
  | otherwise = op e == ops'
  where
    ops' = Set.fromList ops `Set.difference` Set.fromList ["tfold", "bonus"]

{--------------------------------------------------------------------
  Pretty Printing
--------------------------------------------------------------------}