{-# LANGUAGE ImplicitParams #-} {-# LANGUAGE OverloadedStrings #-} module Main where import Control.Monad.IO.Class import Control.Monad.Identity import Data.Time.Clock import Data.Hashable import qualified Data.HashSet as S import qualified Data.HashMap.Strict as M import qualified Data.Maybe as Mb import Debug.Trace import Data.List (intercalate) import Control.Monad import Data.Bifunctor (bimap) import Text.Printf import qualified Arith as A import qualified Compiler as C import qualified Group as G import BagExample import WQODot as WQODot import Language.REST.RESTDot import Language.REST.Dot import DSL import Nat import qualified Set as Set import qualified Multiset as MS import NonTerm as NT import qualified Lists as Li import Language.REST.MultisetOrder (possibilities) import Language.REST.ConcreteOC import Language.REST.Core import Language.REST.AbstractOC import Language.REST.OCToAbstract import Language.REST.Op import Language.REST.OpOrdering import Language.REST.OrderingConstraints as OC import qualified Language.REST.OrderingConstraints.Strict as SC import qualified Language.REST.OrderingConstraints.Lazy as LC import qualified Language.REST.OrderingConstraints.ADT as AC import Language.REST.RPO import Language.REST.WQO as WQO import Language.REST.WorkStrategy import Language.REST.Path import Language.REST.ProofGen import Language.REST.Rest import Language.REST.Types import Language.REST.SMT import qualified Language.REST.MetaTerm as MT import Language.REST.RuntimeTerm as RT import Language.REST.Rewrite data ConsType = Strict | Lazy | ADT mkArithRESTGraph gt ct = mkRESTGraph gt ct A.evalRWs A.userRWs mkCompilerRESTGraph gt ct = mkRESTGraph gt ct C.evalRWs C.userRWs mkGroupRESTGraph gt ct = mkRESTGraph gt ct G.evalRWs G.userRWs mkListsRESTGraph gt ct = mkRESTGraph gt ct Li.evalRWs Li.userRWs mkSetsRESTGraph gt ct = mkRESTGraph gt ct Set.evalRWs Set.userRWs mkNonTermRestGraph gt ct = mkRESTGraph gt ct NT.evalRWs NT.userRWs mkMSRESTGraph gt ct = mkRESTGraph gt ct MS.evalRWs MS.userRWs explain z3 (t, u) = printf "%s ≥ %s requires:\n%s\n\n\n" (show t) (show u) (show $ rpoGTE t u) where ?impl = AC.adtOC z3 explainOrient :: [String] -> IO () explainOrient ts0 = withZ3 go where go z3 = let ts = map parseTerm ts0 pairs = zip ts (tail ts) in do mapM_ (explain z3) pairs printf "Result:\n%s\n" (show $ orient ts) (isSatisfiable (AC.adtOC z3) (orient ts)) >>= print where ?impl = lift (AC.adtOC z3) rpo mkRESTGraph :: (MonadIO m, Hashable (c Op), Ord (c Op), Show (c Op)) => GraphType -> (SolverHandle -> OrderingConstraints c m) -> S.HashSet Rewrite -> S.HashSet Rewrite -> String -> String -> String -> m () mkRESTGraph gt oc evalRWs userRWs name term target = -- mkRESTGraph' gt (fuelOC 5) evalRWs userRWs name term target withZ3 $ \z3 -> mkRESTGraph' gt (lift (oc z3) rpo) evalRWs userRWs name term target mkRESTGraph' :: (MonadIO m, Show c, Hashable c, Ord c) => GraphType -> AbstractOC c RuntimeTerm m -> S.HashSet Rewrite -> S.HashSet Rewrite -> String -> String -> String -> m () mkRESTGraph' gt impl evalRWs userRWs name term target = do let pr (Rewrite t u _) = printf "%s → %s" (pp t) (pp u) liftIO $ mapM_ (\rw -> putStrLn $ pr rw) $ S.toList userRWs liftIO $ mapM_ (\rw -> putStrLn $ pr rw) $ S.toList evalRWs start <- liftIO $ getCurrentTime (PathsResult paths, targetPath) <- rest RESTParams { re = evalRWs , ru = userRWs , toET = id , target = if target == "" then Nothing else (Just (parseTerm target)) , workStrategy = notVisitedFirst , ocImpl = impl , initRes = pathsResult } (parseTerm term) end <- liftIO $ getCurrentTime liftIO $ printf "REST run completed, in %s\n" $ show $ diffUTCTime end start liftIO $ putStrLn "Drawing graph" -- let prettyPrinter = PrettyPrinter pr pp show let prettyPrinter = PrettyPrinter pr pp (const "") True liftIO $ writeDot name gt prettyPrinter (toOrderedSet paths) liftIO $ when (target /= "") (case targetPath of Just tp -> printf "FOUND TARGET. Proof:\n%s\n" (toProof tp) Nothing -> printf "TARGET %s NOT FOUND\n" (pp (parseTerm target))) lhs :: RuntimeTerm lhs = "ite(isNull(ys), null, reverse(tail(ys)) + cons(head(ys),null)) + (reverse(tail(ds)) + cons(head(ds), null))" rhs :: RuntimeTerm rhs = "(ite(isNull(ys), null, reverse(tail(ys)) + cons(head(ys), null)) + reverse(tail(ds))) + cons(head(ds), null)" mkWQOGraph :: String -> String -> IO () mkWQOGraph name wqoS = mkWQOGraph' name wqo where Just wqo = parseOO wqoS mkWQOGraph' :: (Ord a, Hashable a, Show a) => String -> WQO.WQO a -> IO () mkWQOGraph' name wqo = mkGraph name (WQODot.toDigraph wqo) main :: IO () main = return ()