module Common.Once (once, oneTD, oneBU, fullTD, fullBU) where import Common.Logic once = somewhere somewhere :: (Logic -> [Logic]) -> Logic -> [Logic] somewhere f p = f p ++ one (somewhere f) p oneTD :: (Logic -> [Logic]) -> Logic -> [Logic] oneTD f p = f p +> one (oneTD f) p oneBU :: (Logic -> [Logic]) -> Logic -> [Logic] oneBU f p = one (oneBU f) p +> f p fullTD :: (Logic -> [Logic]) -> Logic -> [Logic] fullTD f p = [ p'' | p' <- f p, p'' <- full (fullTD f) p' ] fullBU :: (Logic -> [Logic]) -> Logic -> [Logic] fullBU f p = [ p'' | p' <- full (fullBU f) p, p'' <- f p' ] one :: (Logic -> [Logic]) -> Logic -> [Logic] one f p = case p of p :->: q -> make (:->: q) p ++ make (p :->:) q p :<->: q -> make (:<->: q) p ++ make (p :<->:) q p :&&: q -> make (:&&: q) p ++ make (p :&&:) q p :||: q -> make (:||: q) p ++ make (p :||:) q Not p -> make Not p _ -> [] where make :: (Logic -> Logic) -> Logic -> [Logic] make g = map g . f full :: (Logic -> [Logic]) -> Logic -> [Logic] full f p = case p of p :->: q -> [ p' :->: q' | p' <- f p, q' <- f q ] p :<->: q -> [ p' :<->: q' | p' <- f p, q' <- f q ] p :&&: q -> [ p' :&&: q' | p' <- f p, q' <- f q ] p :||: q -> [ p' :||: q' | p' <- f p, q' <- f q ] Not p -> [ Not p' | p' <- f p ] _ -> [p] (+>) :: [a] -> [a] -> [a] [] +> ys = ys xs +> _ = xs