1
1
mirror of https://github.com/anoma/juvix.git synced 2024-12-11 08:25:46 +03:00

Change terminating keyword behavior (#82)

This commit is contained in:
Jonathan Cubides 2022-05-04 18:17:16 +02:00 committed by GitHub
parent 8146b2a91d
commit 7b1371c4b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 49 additions and 30 deletions

View File

@ -6,17 +6,21 @@ import Commands.Extra
import Commands.MicroJuvix import Commands.MicroJuvix
import Commands.MiniHaskell import Commands.MiniHaskell
import Commands.MonoJuvix import Commands.MonoJuvix
import Commands.Termination as T import Commands.Termination as Termination
import Control.Exception qualified as IO import Control.Exception qualified as IO
import Control.Monad.Extra import Control.Monad.Extra
import Data.HashMap.Strict qualified as HashMap
import MiniJuvix.Pipeline import MiniJuvix.Pipeline
import MiniJuvix.Prelude hiding (Doc) import MiniJuvix.Prelude hiding (Doc)
import MiniJuvix.Prelude.Pretty hiding (Doc) import MiniJuvix.Prelude.Pretty hiding (Doc)
import MiniJuvix.Syntax.Abstract.InfoTable qualified as Abstract
import MiniJuvix.Syntax.Abstract.Language qualified as Abstract
import MiniJuvix.Syntax.Abstract.Pretty qualified as Abstract import MiniJuvix.Syntax.Abstract.Pretty qualified as Abstract
import MiniJuvix.Syntax.Concrete.Language qualified as M import MiniJuvix.Syntax.Concrete.Language qualified as Concrete
import MiniJuvix.Syntax.Concrete.Parser qualified as Parser import MiniJuvix.Syntax.Concrete.Parser qualified as Parser
import MiniJuvix.Syntax.Concrete.Scoped.Highlight qualified as Scoper import MiniJuvix.Syntax.Concrete.Scoped.Highlight qualified as Scoper
import MiniJuvix.Syntax.Concrete.Scoped.InfoTable qualified as Scoper import MiniJuvix.Syntax.Concrete.Scoped.InfoTable qualified as Scoper
import MiniJuvix.Syntax.Concrete.Scoped.Name qualified as Scoper
import MiniJuvix.Syntax.Concrete.Scoped.Pretty qualified as Scoper import MiniJuvix.Syntax.Concrete.Scoped.Pretty qualified as Scoper
import MiniJuvix.Syntax.Concrete.Scoped.Pretty.Html import MiniJuvix.Syntax.Concrete.Scoped.Pretty.Html
import MiniJuvix.Syntax.Concrete.Scoped.Scoper qualified as Scoper import MiniJuvix.Syntax.Concrete.Scoped.Scoper qualified as Scoper
@ -24,8 +28,8 @@ import MiniJuvix.Syntax.MicroJuvix.Pretty qualified as Micro
import MiniJuvix.Syntax.MicroJuvix.TypeChecker qualified as MicroTyped import MiniJuvix.Syntax.MicroJuvix.TypeChecker qualified as MicroTyped
import MiniJuvix.Syntax.MiniHaskell.Pretty qualified as MiniHaskell import MiniJuvix.Syntax.MiniHaskell.Pretty qualified as MiniHaskell
import MiniJuvix.Syntax.MonoJuvix.Pretty qualified as Mono import MiniJuvix.Syntax.MonoJuvix.Pretty qualified as Mono
import MiniJuvix.Termination qualified as T import MiniJuvix.Termination qualified as Termination
import MiniJuvix.Termination.CallGraph qualified as A import MiniJuvix.Termination.CallGraph qualified as Termination
import MiniJuvix.Translation.AbstractToMicroJuvix qualified as Micro import MiniJuvix.Translation.AbstractToMicroJuvix qualified as Micro
import MiniJuvix.Translation.MicroJuvixToMonoJuvix qualified as Mono import MiniJuvix.Translation.MicroJuvixToMonoJuvix qualified as Mono
import MiniJuvix.Translation.MonoJuvixToMiniHaskell qualified as MiniHaskell import MiniJuvix.Translation.MonoJuvixToMiniHaskell qualified as MiniHaskell
@ -288,7 +292,7 @@ mkScopePrettyOptions g ScopeOptions {..} =
Scoper._optInlineImports = _scopeInlineImports Scoper._optInlineImports = _scopeInlineImports
} }
parseModuleIO :: FilePath -> IO (M.Module 'M.Parsed 'M.ModuleTop) parseModuleIO :: FilePath -> IO (Concrete.Module 'Concrete.Parsed 'Concrete.ModuleTop)
parseModuleIO = fromRightIO id . Parser.runModuleParserIO parseModuleIO = fromRightIO id . Parser.runModuleParserIO
minijuvixYamlFile :: FilePath minijuvixYamlFile :: FilePath
@ -433,40 +437,46 @@ runCLI cli = do
results <- runIO (upToAbstract (getEntryPoint root opts)) results <- runIO (upToAbstract (getEntryPoint root opts))
let topModule = head (results ^. Abstract.resultModules) let topModule = head (results ^. Abstract.resultModules)
infotable = results ^. Abstract.resultTable infotable = results ^. Abstract.resultTable
callMap0 = T.buildCallMap infotable topModule callMap0 = Termination.buildCallMap infotable topModule
callMap = case _callsFunctionNameFilter of callMap = case _callsFunctionNameFilter of
Nothing -> callMap0 Nothing -> callMap0
Just f -> T.filterCallMap f callMap0 Just f -> Termination.filterCallMap f callMap0
opts' = T.callsPrettyOptions opts opts' = Termination.callsPrettyOptions opts
renderStdOutAbs (Abstract.ppOut opts' callMap) renderStdOutAbs (Abstract.ppOut opts' callMap)
putStrLn "" putStrLn ""
Termination (CallGraph opts@CallGraphOptions {..}) -> do Termination (CallGraph opts@CallGraphOptions {..}) -> do
results <- runIO (upToAbstract (getEntryPoint root opts)) results <- runIO (upToAbstract (getEntryPoint root opts))
let topModule = head (results ^. Abstract.resultModules) let topModule = head (results ^. Abstract.resultModules)
infotable = results ^. Abstract.resultTable infotable = results ^. Abstract.resultTable
callMap = T.buildCallMap infotable topModule callMap = Termination.buildCallMap infotable topModule
opts' = opts' =
Abstract.defaultOptions Abstract.defaultOptions
{ Abstract._optShowNameId = globalOptions ^. globalShowNameIds { Abstract._optShowNameId = globalOptions ^. globalShowNameIds
} }
completeGraph = T.completeCallGraph callMap completeGraph = Termination.completeCallGraph callMap
filteredGraph = maybe completeGraph (`T.unsafeFilterGraph` completeGraph) _graphFunctionNameFilter filteredGraph = maybe completeGraph (`Termination.unsafeFilterGraph` completeGraph) _graphFunctionNameFilter
rEdges = T.reflexiveEdges filteredGraph rEdges = Termination.reflexiveEdges filteredGraph
recBehav = map Termination.recursiveBehaviour rEdges
recBehav = map T.recursiveBehaviour rEdges
renderStdOutAbs (Abstract.ppOut opts' filteredGraph) renderStdOutAbs (Abstract.ppOut opts' filteredGraph)
putStrLn "" putStrLn ""
forM_ recBehav $ \r -> do forM_ recBehav $ \r -> do
let sopts = let funName = Termination._recursiveBehaviourFun r
funRef = Abstract.FunctionRef (Scoper.unqualifiedSymbol funName)
funInfo = HashMap.lookupDefault impossible funRef (infotable ^. Abstract.infoFunctions)
markedTerminating = funInfo ^. (Abstract.functionInfoDef . Abstract.funDefTerminating)
sopts =
Scoper.defaultOptions Scoper.defaultOptions
{ Scoper._optShowNameId = globalOptions ^. globalShowNameIds { Scoper._optShowNameId = globalOptions ^. globalShowNameIds
} }
n = toAnsiText' (Scoper.ppOut sopts (A._recursiveBehaviourFun r)) n = toAnsiText' (Scoper.ppOut sopts funName)
renderStdOutAbs (Abstract.ppOut opts' r) renderStdOutAbs (Abstract.ppOut opts' r)
putStrLn "" putStrLn ""
case T.findOrder r of if
Nothing -> putStrLn (n <> " Fails the termination checking") >> exitFailure | markedTerminating -> putStrLn (n <> " Terminates by assumption ")
Just (T.LexOrder k) -> putStrLn (n <> " Terminates with order " <> show (toList k)) | otherwise ->
case Termination.findOrder r of
Nothing -> putStrLn (n <> " Fails the termination checking") >> exitFailure
Just (Termination.LexOrder k) -> putStrLn (n <> " Terminates with order " <> show (toList k))
putStrLn "" putStrLn ""
main :: IO () main :: IO ()

View File

@ -152,17 +152,8 @@ checkExpression ::
checkExpression e = checkExpression e =
viewCall e >>= \case viewCall e >>= \case
Just c -> do Just c -> do
h <- asks _infoFunctions registerCall c
let fname = c ^. callRef mapM_ (checkExpression . snd) (c ^. callArgs)
info = HashMap.lookupDefault impossible fname h
markedTerminating = info ^. (functionInfoDef . funDefTerminating)
if
| markedTerminating -> do
let cargs = map (\x -> (CallRow (Just (0, RLe)), snd x)) (c ^. callArgs)
registerCall $ FunCall fname cargs
| otherwise -> do
registerCall c
mapM_ (checkExpression . snd) (c ^. callArgs)
Nothing -> case e of Nothing -> case e of
ExpressionApplication a -> checkApplication a ExpressionApplication a -> checkApplication a
ExpressionFunction f -> checkFunction f ExpressionFunction f -> checkFunction f

View File

@ -0,0 +1,11 @@
module Mutual;
axiom A : Type;
terminating f : A -> A -> A;
terminating g : A -> A -> A;
g x y := f x x;
f x y := g x (f x x);
end;

View File

@ -0,0 +1,7 @@
module Undefined;
axiom A : Type;
terminating undefined : A;
undefined := undefined;
end;