1
1
mirror of https://github.com/anoma/juvix.git synced 2024-09-11 16:26:33 +03:00

Numeric, ordering and equality traits (#2433)

* Adapts to https://github.com/anoma/juvix-stdlib/pull/86
* Adds a pass in `toEvalTransformations` to automatically inline all
record projection functions, regardless of the optimization level. This
is necessary to ensure that arithmetic operations and comparisons on
`Nat` or `Int` are always represented directly with the corresponding
built-in Core functions. This is generally highly desirable and required
for the Geb target.
* Adds the `inline: always` pragma which indicates that a function
should always be inlined during the mandatory inlining phase, regardless
of optimization level.
This commit is contained in:
Łukasz Czajka 2023-10-09 18:25:01 +02:00 committed by GitHub
parent 0e4c27b74f
commit 60a191b786
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
79 changed files with 170 additions and 141 deletions

View File

@ -2,9 +2,6 @@ module Demo;
-- standard library prelude -- standard library prelude
import Stdlib.Prelude open; import Stdlib.Prelude open;
-- for comparisons on natural numbers
import Stdlib.Data.Nat.Ord open;
-- for Ordering
even : Nat → Bool even : Nat → Bool
| zero := true | zero := true
@ -35,13 +32,13 @@ preorder : {A : Type} → Tree A → List A
| (node x l r) := x :: nil ++ preorder l ++ preorder r; | (node x l r) := x :: nil ++ preorder l ++ preorder r;
terminating terminating
sort : {A : Type} → (A → A → Ordering) → List A → List A sort {A} {{Ord A}} : List A → List A
| _ nil := nil | nil := nil
| _ xs@(_ :: nil) := xs | xs@(_ :: nil) := xs
| {A} cmp xs := | xs :=
uncurry uncurry
(merge {{mkOrd cmp}}) merge
(both (sort cmp) (splitAt (div (length xs) 2) xs)); (both sort (splitAt (div (length xs) 2) xs));
printNatListLn : List Nat → IO printNatListLn : List Nat → IO
| nil := printStringLn "nil" | nil := printStringLn "nil"
@ -51,6 +48,6 @@ printNatListLn : List Nat → IO
main : IO := main : IO :=
printStringLn "Hello!" printStringLn "Hello!"
>> printNatListLn (preorder (mirror tree)) >> printNatListLn (preorder (mirror tree))
>> printNatListLn (sort compare (preorder (mirror tree))) >> printNatListLn (sort (preorder (mirror tree)))
>> printNatLn (log2 3) >> printNatLn (log2 3)
>> printNatLn (log2 130); >> printNatLn (log2 130);

View File

@ -5,7 +5,6 @@
module MidSquareHash; module MidSquareHash;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
--- `pow N` is 2 ^ N --- `pow N` is 2 ^ N
pow : Nat -> Nat pow : Nat -> Nat

View File

@ -6,7 +6,6 @@
module MidSquareHashUnrolled; module MidSquareHashUnrolled;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
--- `powN` is 2 ^ N --- `powN` is 2 ^ N
pow0 : Nat := 1; pow0 : Nat := 1;

View File

@ -6,8 +6,6 @@ module Bank;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Debug.Fail open; import Stdlib.Debug.Fail open;
import Stdlib.Data.Nat.Ord open;
import Stdlib.Data.Nat as Nat; import Stdlib.Data.Nat as Nat;
Address : Type := Nat; Address : Type := Nat;

View File

@ -1,7 +1,6 @@
module Collatz; module Collatz;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
collatzNext (n : Nat) : Nat := collatzNext (n : Nat) : Nat :=
if (mod n 2 == 0) (div n 2) (3 * n + 1); if (mod n 2 == 0) (div n 2) (3 * n + 1);

View File

@ -5,7 +5,6 @@
--- The module Logic.Game contains the game logic. --- The module Logic.Game contains the game logic.
module CLI.TicTacToe; module CLI.TicTacToe;
import Stdlib.Data.Nat.Ord open;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Logic.Game open; import Logic.Game open;

View File

@ -1,7 +1,6 @@
--- Some generic helper definitions. --- Some generic helper definitions.
module Logic.Extra; module Logic.Extra;
import Stdlib.Data.Nat.Ord open;
import Stdlib.Prelude open; import Stdlib.Prelude open;
--- Concatenates a list of strings --- Concatenates a list of strings

View File

@ -4,7 +4,6 @@
--- diagonal row is the winner. It is a solved game, with a forced draw assuming best play from both players. --- diagonal row is the winner. It is a solved game, with a forced draw assuming best play from both players.
module Logic.Game; module Logic.Game;
import Stdlib.Data.Nat.Ord open;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Logic.Extra open public; import Logic.Extra open public;
import Logic.Board open public; import Logic.Board open public;

View File

@ -2,7 +2,6 @@ module Logic.Square;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Logic.Symbol open; import Logic.Symbol open;
import Stdlib.Data.Nat.Ord open;
import Logic.Extra open; import Logic.Extra open;
--- A square is each of the holes in a board --- A square is each of the holes in a board
@ -24,9 +23,5 @@ showSquare : Square → String
| (occupied s) := " " ++str showSymbol s ++str " "; | (occupied s) := " " ++str showSymbol s ++str " ";
replace (player : Symbol) (k : Nat) : Square → Square replace (player : Symbol) (k : Nat) : Square → Square
| (empty n) := | (empty n) := if (n == k) (occupied player) (empty n)
if
(n Stdlib.Data.Nat.Ord.== k)
(occupied player)
(empty n)
| s := s; | s := s;

View File

@ -5,7 +5,5 @@ module Tutorial;
-- import the standard library prelude and bring it into scope -- import the standard library prelude and bring it into scope
import Stdlib.Prelude open; import Stdlib.Prelude open;
-- bring comparison operators on Nat into scope
import Stdlib.Data.Nat.Ord open;
main : IO := printStringLn "Hello world!"; main : IO := printStringLn "Hello world!";

@ -1 +1 @@
Subproject commit adf58a7180b361a022fb53c22ad9e5274ebf6f66 Subproject commit 9a091c5453594ac66b3b25cde0c11a54a255a9c9

View File

@ -58,7 +58,7 @@ fromCore :: Core.InfoTable -> (Morphism, Object)
fromCore tab = case tab ^. Core.infoMain of fromCore tab = case tab ^. Core.infoMain of
Just sym -> Just sym ->
let node = Core.lookupIdentifierNode tab sym let node = Core.lookupIdentifierNode tab sym
syms = reverse $ filter (/= sym) $ Core.createIdentDependencyInfo tab ^. Core.depInfoTopSort syms = reverse $ filter (/= sym) $ Core.createCallGraph tab ^. Core.depInfoTopSort
idents = map (Core.lookupIdentifierInfo tab) syms idents = map (Core.lookupIdentifierInfo tab) syms
morph = run . runReader emptyEnv $ goIdents node idents morph = run . runReader emptyEnv $ goIdents node idents
obj = convertType $ Info.getNodeType node obj = convertType $ Info.getNodeType node

View File

@ -1,5 +1,6 @@
module Juvix.Compiler.Core.Data.IdentDependencyInfo where module Juvix.Compiler.Core.Data.IdentDependencyInfo where
import Data.HashMap.Strict qualified as HashMap
import Data.HashSet qualified as HashSet import Data.HashSet qualified as HashSet
import Juvix.Compiler.Core.Data.InfoTable import Juvix.Compiler.Core.Data.InfoTable
import Juvix.Compiler.Core.Extra.Utils import Juvix.Compiler.Core.Extra.Utils
@ -9,8 +10,8 @@ import Juvix.Compiler.Core.Language
type IdentDependencyInfo = DependencyInfo Symbol type IdentDependencyInfo = DependencyInfo Symbol
-- | Compute the call graph -- | Compute the call graph
createIdentDependencyInfo :: InfoTable -> IdentDependencyInfo createCallGraph :: InfoTable -> IdentDependencyInfo
createIdentDependencyInfo tab = createDependencyInfo graph startVertices createCallGraph tab = createDependencyInfo graph startVertices
where where
graph :: HashMap Symbol (HashSet Symbol) graph :: HashMap Symbol (HashSet Symbol)
graph = graph =
@ -27,5 +28,28 @@ createIdentDependencyInfo tab = createDependencyInfo graph startVertices
syms :: [Symbol] syms :: [Symbol]
syms = maybe [] singleton (tab ^. infoMain) syms = maybe [] singleton (tab ^. infoMain)
createSymbolDependencyInfo :: InfoTable -> IdentDependencyInfo
createSymbolDependencyInfo tab = createDependencyInfo graph startVertices
where
graph :: HashMap Symbol (HashSet Symbol)
graph =
fmap
( \IdentifierInfo {..} ->
getSymbols tab (lookupIdentifierNode tab _identifierSymbol)
)
(tab ^. infoIdentifiers)
<> foldr
( \ConstructorInfo {..} ->
HashMap.insert _constructorInductive (getSymbols tab _constructorType)
)
mempty
(tab ^. infoConstructors)
startVertices :: HashSet Symbol
startVertices = HashSet.fromList syms
syms :: [Symbol]
syms = maybe [] singleton (tab ^. infoMain)
recursiveIdents :: InfoTable -> HashSet Symbol recursiveIdents :: InfoTable -> HashSet Symbol
recursiveIdents = nodesOnCycles . createIdentDependencyInfo recursiveIdents = nodesOnCycles . createCallGraph

View File

@ -209,20 +209,33 @@ filterByFile f t =
matchesLocation :: Maybe Location -> Bool matchesLocation :: Maybe Location -> Bool
matchesLocation l = l ^? _Just . intervalFile == Just f matchesLocation l = l ^? _Just . intervalFile == Just f
-- | Prunes the orphaned entries of identMap and indentContext, i.e., ones that -- | Prunes the orphaned entries of identMap, indentContext and
-- have no corresponding entries in infoIdentifiers or infoInductives -- infoConstructors, i.e., ones that have no corresponding entries in
-- infoIdentifiers or infoInductives
pruneInfoTable :: InfoTable -> InfoTable pruneInfoTable :: InfoTable -> InfoTable
pruneInfoTable tab = pruneInfoTable tab =
over pruneIdentMap
identMap $ over
( HashMap.filter infoConstructors
( \case ( HashMap.filter
IdentFun s -> HashMap.member s (tab ^. infoIdentifiers) ( \ConstructorInfo {..} ->
IdentInd s -> HashMap.member s (tab ^. infoInductives) HashMap.member _constructorInductive (tab ^. infoInductives)
IdentConstr tag -> HashMap.member tag (tab ^. infoConstructors) )
) )
)
$ over $ over
identContext identContext
(HashMap.filterWithKey (\s _ -> HashMap.member s (tab ^. infoIdentifiers))) (HashMap.filterWithKey (\s _ -> HashMap.member s (tab ^. infoIdentifiers)))
tab tab
where
pruneIdentMap :: InfoTable -> InfoTable
pruneIdentMap tab' =
over
identMap
( HashMap.filter
( \case
IdentFun s -> HashMap.member s (tab' ^. infoIdentifiers)
IdentInd s -> HashMap.member s (tab' ^. infoInductives)
IdentConstr tag -> HashMap.member tag (tab' ^. infoConstructors)
)
)
tab'

View File

@ -26,6 +26,7 @@ data TransformationId
| LambdaFolding | LambdaFolding
| LetHoisting | LetHoisting
| Inlining | Inlining
| MandatoryInlining
| FoldTypeSynonyms | FoldTypeSynonyms
| CaseCallLifting | CaseCallLifting
| SimplifyIfs | SimplifyIfs
@ -75,7 +76,7 @@ toNormalizeTransformations :: [TransformationId]
toNormalizeTransformations = toEvalTransformations ++ [LetRecLifting, LetFolding, UnrollRecursion] toNormalizeTransformations = toEvalTransformations ++ [LetRecLifting, LetFolding, UnrollRecursion]
toVampIRTransformations :: [TransformationId] toVampIRTransformations :: [TransformationId]
toVampIRTransformations = toEvalTransformations ++ [CheckVampIR, LetRecLifting, OptPhaseVampIR, UnrollRecursion, Normalize, LetHoisting] toVampIRTransformations = toEvalTransformations ++ [FilterUnreachable, CheckVampIR, LetRecLifting, OptPhaseVampIR, UnrollRecursion, Normalize, LetHoisting]
toStrippedTransformations :: [TransformationId] toStrippedTransformations :: [TransformationId]
toStrippedTransformations = toStrippedTransformations =

View File

@ -86,6 +86,7 @@ transformationText = \case
LambdaFolding -> strLambdaFolding LambdaFolding -> strLambdaFolding
LetHoisting -> strLetHoisting LetHoisting -> strLetHoisting
Inlining -> strInlining Inlining -> strInlining
MandatoryInlining -> strMandatoryInlining
FoldTypeSynonyms -> strFoldTypeSynonyms FoldTypeSynonyms -> strFoldTypeSynonyms
CaseCallLifting -> strCaseCallLifting CaseCallLifting -> strCaseCallLifting
SimplifyIfs -> strSimplifyIfs SimplifyIfs -> strSimplifyIfs
@ -191,6 +192,9 @@ strLambdaFolding = "lambda-folding"
strInlining :: Text strInlining :: Text
strInlining = "inlining" strInlining = "inlining"
strMandatoryInlining :: Text
strMandatoryInlining = "mandatory-inlining"
strFoldTypeSynonyms :: Text strFoldTypeSynonyms :: Text
strFoldTypeSynonyms = "fold-type-synonyms" strFoldTypeSynonyms = "fold-type-synonyms"

View File

@ -89,7 +89,7 @@ geval opts herr ctx env0 = eval' env0
Closure env' (NLam (Lambda i' bi b)) -> Closure env' (NLam (Lambda i' bi b)) ->
let !v = eval' env r in evalBody i' bi env' v b let !v = eval' env r in evalBody i' bi env' v b
lv lv
| opts ^. evalOptionsNormalize -> | opts ^. evalOptionsNormalize || opts ^. evalOptionsNoFailure ->
let !v = eval' env r in goNormApp i lv v let !v = eval' env r in goNormApp i lv v
| otherwise -> | otherwise ->
evalError "invalid application" (mkApp i lv (substEnv env r)) evalError "invalid application" (mkApp i lv (substEnv env r))
@ -106,7 +106,7 @@ geval opts herr ctx env0 = eval' env0
NCtr (Constr _ tag args) -> NCtr (Constr _ tag args) ->
branch n env args tag def bs branch n env args tag def bs
v' v'
| opts ^. evalOptionsNormalize -> | opts ^. evalOptionsNormalize || opts ^. evalOptionsNoFailure ->
goNormCase env i sym v' bs def goNormCase env i sym v' bs def
| otherwise -> | otherwise ->
evalError "matching on non-data" (substEnv env (mkCase i sym v' bs def)) evalError "matching on non-data" (substEnv env (mkCase i sym v' bs def))
@ -214,7 +214,7 @@ geval opts herr ctx env0 = eval' env0
(Just v1, Just v2) -> (Just v1, Just v2) ->
toNode (v1 `op` v2) toNode (v1 `op` v2)
_ _
| opts ^. evalOptionsNormalize -> | opts ^. evalOptionsNormalize || opts ^. evalOptionsNoFailure ->
mkBuiltinApp' opcode [vl, vr] mkBuiltinApp' opcode [vl, vr]
| otherwise -> | otherwise ->
evalError "wrong operand type" n evalError "wrong operand type" n

View File

@ -144,6 +144,9 @@ nodeIdents f = ufoldA reassemble go
NIdt i -> NIdt <$> f i NIdt i -> NIdt <$> f i
n -> pure n n -> pure n
getInductives :: Node -> HashSet Symbol
getInductives n = HashSet.fromList (n ^.. nodeInductives)
nodeInductives :: Traversal' Node Symbol nodeInductives :: Traversal' Node Symbol
nodeInductives f = ufoldA reassemble go nodeInductives f = ufoldA reassemble go
where where
@ -151,6 +154,19 @@ nodeInductives f = ufoldA reassemble go
NTyp ty -> NTyp <$> traverseOf typeConstrSymbol f ty NTyp ty -> NTyp <$> traverseOf typeConstrSymbol f ty
n -> pure n n -> pure n
getSymbols :: InfoTable -> Node -> HashSet Symbol
getSymbols tab = gather go mempty
where
go :: HashSet Symbol -> Node -> HashSet Symbol
go acc = \case
NTyp TypeConstr {..} -> HashSet.insert _typeConstrSymbol acc
NIdt Ident {..} -> HashSet.insert _identSymbol acc
NCase Case {..} -> HashSet.insert _caseInductive acc
NCtr Constr {..}
| Just ci <- lookupConstructorInfo' tab _constrTag ->
HashSet.insert (ci ^. constructorInductive) acc
_ -> acc
-- | Prism for NRec -- | Prism for NRec
_NRec :: SimpleFold Node LetRec _NRec :: SimpleFold Node LetRec
_NRec f = \case _NRec f = \case

View File

@ -35,6 +35,7 @@ import Juvix.Compiler.Core.Transformation.Optimize.FilterUnreachable (filterUnre
import Juvix.Compiler.Core.Transformation.Optimize.Inlining import Juvix.Compiler.Core.Transformation.Optimize.Inlining
import Juvix.Compiler.Core.Transformation.Optimize.LambdaFolding import Juvix.Compiler.Core.Transformation.Optimize.LambdaFolding
import Juvix.Compiler.Core.Transformation.Optimize.LetFolding import Juvix.Compiler.Core.Transformation.Optimize.LetFolding
import Juvix.Compiler.Core.Transformation.Optimize.MandatoryInlining
import Juvix.Compiler.Core.Transformation.Optimize.Phase.Eval qualified as Phase.Eval import Juvix.Compiler.Core.Transformation.Optimize.Phase.Eval qualified as Phase.Eval
import Juvix.Compiler.Core.Transformation.Optimize.Phase.Exec qualified as Phase.Exec import Juvix.Compiler.Core.Transformation.Optimize.Phase.Exec qualified as Phase.Exec
import Juvix.Compiler.Core.Transformation.Optimize.Phase.Geb qualified as Phase.Geb import Juvix.Compiler.Core.Transformation.Optimize.Phase.Geb qualified as Phase.Geb
@ -74,6 +75,7 @@ applyTransformations ts tbl = foldM (flip appTrans) tbl ts
LambdaFolding -> return . lambdaFolding LambdaFolding -> return . lambdaFolding
LetHoisting -> return . letHoisting LetHoisting -> return . letHoisting
Inlining -> inlining Inlining -> inlining
MandatoryInlining -> return . mandatoryInlining
FoldTypeSynonyms -> return . foldTypeSynonyms FoldTypeSynonyms -> return . foldTypeSynonyms
CaseCallLifting -> return . caseCallLifting CaseCallLifting -> return . caseCallLifting
SimplifyIfs -> return . simplifyIfs SimplifyIfs -> return . simplifyIfs

View File

@ -1,4 +1,4 @@
-- Moves al let expressions at the top, just after the top lambdas. This -- Moves all let expressions at the top, just after the top lambdas. This
-- transformation assumes: -- transformation assumes:
-- - There are no LetRecs, Lambdas (other than the ones at the top), nor Match. -- - There are no LetRecs, Lambdas (other than the ones at the top), nor Match.
-- - Case nodes do not have binders. -- - Case nodes do not have binders.

View File

@ -5,10 +5,13 @@ import Juvix.Compiler.Core.Data.IdentDependencyInfo
import Juvix.Compiler.Core.Transformation.Base import Juvix.Compiler.Core.Transformation.Base
filterUnreachable :: InfoTable -> InfoTable filterUnreachable :: InfoTable -> InfoTable
filterUnreachable tab = pruneInfoTable $ over infoIdentifiers goFilter tab filterUnreachable tab =
pruneInfoTable $
over infoInductives goFilter $
over infoIdentifiers goFilter tab
where where
depInfo = createIdentDependencyInfo tab depInfo = createSymbolDependencyInfo tab
goFilter :: HashMap Symbol IdentifierInfo -> HashMap Symbol IdentifierInfo goFilter :: HashMap Symbol a -> HashMap Symbol a
goFilter idents = goFilter =
HashMap.filterWithKey (\sym _ -> isReachable depInfo sym) idents HashMap.filterWithKey (\sym _ -> isReachable depInfo sym)

View File

@ -32,6 +32,8 @@ convertNode inlineDepth recSyms tab = dmapL go
Just (InlinePartiallyApplied k) Just (InlinePartiallyApplied k)
| length args >= k -> | length args >= k ->
mkApps def args mkApps def args
Just InlineAlways ->
mkApps def args
Just InlineNever -> Just InlineNever ->
node node
_ _
@ -48,6 +50,17 @@ convertNode inlineDepth recSyms tab = dmapL go
def = lookupIdentifierNode tab _identSymbol def = lookupIdentifierNode tab _identSymbol
_ -> _ ->
node node
NIdt Ident {..} ->
case pi of
Just InlineFullyApplied | argsNum == 0 -> def
Just (InlinePartiallyApplied 0) -> def
Just InlineAlways -> def
_ -> node
where
ii = lookupIdentifierInfo tab _identSymbol
pi = ii ^. identifierPragmas . pragmasInline
argsNum = ii ^. identifierArgsNum
def = lookupIdentifierNode tab _identSymbol
-- inline zero-argument definitions automatically if inlining would result -- inline zero-argument definitions automatically if inlining would result
-- in case reduction -- in case reduction
NCase cs@Case {..} -> case _caseValue of NCase cs@Case {..} -> case _caseValue of

View File

@ -0,0 +1,18 @@
module Juvix.Compiler.Core.Transformation.Optimize.MandatoryInlining where
import Juvix.Compiler.Core.Extra
import Juvix.Compiler.Core.Transformation.Base
convertNode :: InfoTable -> Node -> Node
convertNode tab = dmap go
where
go :: Node -> Node
go node = case node of
NIdt Ident {..}
| Just InlineAlways <- lookupIdentifierInfo tab _identSymbol ^. identifierPragmas . pragmasInline ->
lookupIdentifierNode tab _identSymbol
_ ->
node
mandatoryInlining :: InfoTable -> InfoTable
mandatoryInlining tab = mapAllNodes (convertNode tab) tab

View File

@ -1,11 +1,15 @@
module Juvix.Compiler.Core.Transformation.Optimize.Phase.Eval where module Juvix.Compiler.Core.Transformation.Optimize.Phase.Eval where
import Juvix.Compiler.Core.Options
import Juvix.Compiler.Core.Transformation.Base import Juvix.Compiler.Core.Transformation.Base
import Juvix.Compiler.Core.Transformation.Optimize.CaseFolding
import Juvix.Compiler.Core.Transformation.Optimize.LambdaFolding import Juvix.Compiler.Core.Transformation.Optimize.LambdaFolding
import Juvix.Compiler.Core.Transformation.Optimize.LetFolding import Juvix.Compiler.Core.Transformation.Optimize.LetFolding
import Juvix.Compiler.Core.Transformation.Optimize.MandatoryInlining
optimize :: (Member (Reader CoreOptions) r) => InfoTable -> Sem r InfoTable optimize :: InfoTable -> Sem r InfoTable
optimize = optimize =
withOptimizationLevel 1 $ return
return . letFolding . lambdaFolding . caseFolding
. letFolding
. lambdaFolding
. mandatoryInlining

View File

@ -13,7 +13,7 @@ unrollRecursion tab = do
(mp, tab') <- (mp, tab') <-
runState @(HashMap Symbol Symbol) mempty $ runState @(HashMap Symbol Symbol) mempty $
execInfoTableBuilder tab $ execInfoTableBuilder tab $
forM_ (buildSCCs (createIdentDependencyInfo tab)) goSCC forM_ (buildSCCs (createCallGraph tab)) goSCC
return $ mapIdentSymbols mp $ pruneInfoTable tab' return $ mapIdentSymbols mp $ pruneInfoTable tab'
where where
mapIdentSymbols :: HashMap Symbol Symbol -> InfoTable -> InfoTable mapIdentSymbols :: HashMap Symbol Symbol -> InfoTable -> InfoTable

View File

@ -93,7 +93,7 @@ genFieldProjection _funDefName info fieldIx = do
_funDefTerminating = False, _funDefTerminating = False,
_funDefInstance = False, _funDefInstance = False,
_funDefBuiltin = Nothing, _funDefBuiltin = Nothing,
_funDefPragmas = mempty, _funDefPragmas = mempty {_pragmasInline = Just InlineAlways},
_funDefBody = body', _funDefBody = body',
_funDefType = foldFunType (inductiveArgs ++ [saturatedTy]) retTy, _funDefType = foldFunType (inductiveArgs ++ [saturatedTy]) retTy,
.. ..

View File

@ -5,7 +5,8 @@ import Juvix.Data.Yaml
import Juvix.Prelude.Base import Juvix.Prelude.Base
data PragmaInline data PragmaInline
= InlineNever = InlineAlways
| InlineNever
| InlineFullyApplied | InlineFullyApplied
| InlinePartiallyApplied {_pragmaInlineArgsNum :: Int} | InlinePartiallyApplied {_pragmaInlineArgsNum :: Int}
deriving stock (Show, Eq, Ord, Data, Generic) deriving stock (Show, Eq, Ord, Data, Generic)
@ -116,7 +117,7 @@ instance FromJSON Pragmas where
return Pragmas {..} return Pragmas {..}
parseInline :: Parse YamlError PragmaInline parseInline :: Parse YamlError PragmaInline
parseInline = parseInlineArgsNum Aeson.<|> parseInlineBool parseInline = parseInlineArgsNum Aeson.<|> parseInlineBool Aeson.<|> parseInlineAlwaysNever
where where
parseInlineArgsNum :: Parse YamlError PragmaInline parseInlineArgsNum :: Parse YamlError PragmaInline
parseInlineArgsNum = do parseInlineArgsNum = do
@ -128,6 +129,14 @@ instance FromJSON Pragmas where
b <- asBool b <- asBool
(if b then return InlineFullyApplied else return InlineNever) (if b then return InlineFullyApplied else return InlineNever)
parseInlineAlwaysNever :: Parse YamlError PragmaInline
parseInlineAlwaysNever = do
txt <- asText
case txt of
"always" -> return InlineAlways
"never" -> return InlineNever
_ -> throwCustomError ("unrecognized inline specification: " <> txt)
parseUnroll :: Parse YamlError PragmaUnroll parseUnroll :: Parse YamlError PragmaUnroll
parseUnroll = do parseUnroll = do
_pragmaUnrollDepth <- asIntegral _pragmaUnrollDepth <- asIntegral
@ -209,6 +218,7 @@ instance Monoid Pragmas where
adjustPragmaInline :: Int -> PragmaInline -> PragmaInline adjustPragmaInline :: Int -> PragmaInline -> PragmaInline
adjustPragmaInline n = \case adjustPragmaInline n = \case
InlinePartiallyApplied k -> InlinePartiallyApplied (k + n) InlinePartiallyApplied k -> InlinePartiallyApplied (k + n)
InlineAlways -> InlineAlways
InlineNever -> InlineNever InlineNever -> InlineNever
InlineFullyApplied -> InlineFullyApplied InlineFullyApplied -> InlineFullyApplied

View File

@ -44,5 +44,5 @@ liftTest _testEval =
checkNoRecursion :: InfoTable -> Assertion checkNoRecursion :: InfoTable -> Assertion
checkNoRecursion tab = checkNoRecursion tab =
when when
(isCyclic (createIdentDependencyInfo tab)) (isCyclic (createCallGraph tab))
(assertFailure "recursion detected") (assertFailure "recursion detected")

View File

@ -2,7 +2,6 @@
module test006; module test006;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
loop : Nat := loop; loop : Nat := loop;

View File

@ -2,7 +2,6 @@
module test012; module test012;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type Tree := type Tree :=
| leaf : Tree | leaf : Tree

View File

@ -2,7 +2,6 @@
module test013; module test013;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
f : Nat → Nat → Nat f : Nat → Nat → Nat
| x := | x :=

View File

@ -2,7 +2,6 @@
module test015; module test015;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
f : Nat → Nat → Nat f : Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module test020; module test020;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
-- McCarthy's 91 function -- McCarthy's 91 function
terminating terminating

View File

@ -2,7 +2,6 @@
module test021; module test021;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
power' : Nat → Nat → Nat → Nat power' : Nat → Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module test022; module test022;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
gen : Nat → List Nat gen : Nat → List Nat
| zero := nil | zero := nil

View File

@ -2,11 +2,10 @@
module test023; module test023;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
f : Nat → Nat f : Nat → Nat
| x := if (x < 1) 1 (2 * x + g (sub x 1)); | x := if (x < 1) 1 (2 * x + g (sub x 1));
terminating terminating

View File

@ -2,7 +2,6 @@
module test025; module test025;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
gcd : Nat → Nat → Nat gcd : Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module test028; module test028;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type Stream := type Stream :=
| cons : Nat → (Unit → Stream) → Stream; | cons : Nat → (Unit → Stream) → Stream;

View File

@ -2,7 +2,6 @@
module test032; module test032;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
split : {A : Type} → Nat → List A → List A × List A split : {A : Type} → Nat → List A → List A × List A
| zero xs := nil, xs | zero xs := nil, xs

View File

@ -2,7 +2,6 @@
module test034; module test034;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
sum : Nat → Nat := sum : Nat → Nat :=
let let

View File

@ -1,9 +1,7 @@
-- Builtin Int -- Builtin Int
module test049; module test049;
import Stdlib.Prelude open hiding {+; *; div; mod}; import Stdlib.Prelude open;
import Stdlib.Data.Int.Ord open;
import Stdlib.Data.Int open;
f : Int -> Nat f : Int -> Nat
| (negSuc n) := n | (negSuc n) := n
@ -23,8 +21,8 @@ main : IO :=
>> printBoolLn (-1 == -2) >> printBoolLn (-1 == -2)
>> printBoolLn (-1 == -1) >> printBoolLn (-1 == -1)
>> printBoolLn (1 == 1) >> printBoolLn (1 == 1)
>> printBoolLn (-1 == 1) >> printBoolLn (-1 == ofNat 1)
>> printIntLn (-1 + 1) >> printIntLn (-1 + ofNat 1)
>> printIntLn (negNat (suc zero)) >> printIntLn (negNat (suc zero))
>> printIntLn >> printIntLn
(let (let
@ -35,9 +33,9 @@ main : IO :=
(let (let
g : Int -> Int := neg; g : Int -> Int := neg;
in g -1) in g -1)
>> printIntLn (-2 * 2) >> printIntLn (-2 * ofNat 2)
>> printIntLn (div 4 -2) >> printIntLn (div (ofNat 4) -2)
>> printIntLn (2 - 2) >> printIntLn (ofNat 2 - ofNat 2)
>> printBoolLn (nonNeg 0) >> printBoolLn (nonNeg 0)
>> printBoolLn (nonNeg -1) >> printBoolLn (nonNeg -1)
>> printIntLn (mod -5 -2) >> printIntLn (mod -5 -2)
@ -45,5 +43,5 @@ main : IO :=
>> printBoolLn (0 <= 0) >> printBoolLn (0 <= 0)
>> printBoolLn (0 < 1) >> printBoolLn (0 < 1)
>> printBoolLn (1 <= 0) >> printBoolLn (1 <= 0)
>> printIntLn (mod 5 -3) >> printIntLn (mod (ofNat 5) -3)
>> printIntLn (div 5 -3); >> printIntLn (div (ofNat 5) -3);

View File

@ -1,13 +1,11 @@
-- Pattern matching with integers -- Pattern matching with integers
module test050; module test050;
import Stdlib.Prelude open hiding {+; *; div; mod}; import Stdlib.Prelude open;
import Stdlib.Data.Int.Ord open;
import Stdlib.Data.Int open;
f : Int -> Int f : Int -> Int
| (negSuc zero) := ofNat 0 | (negSuc zero) := ofNat 0
| (negSuc m@(suc n)) := ofNat n + ofNat m | (negSuc m@(suc n)) := ofNat n + ofNat m
| (ofNat n) := neg (ofNat n - 7); | (ofNat n) := neg (ofNat n - ofNat 7);
main : Int := f -10 - f 1 + f -1; main : Int := f -10 - f 1 + f -1;

View File

@ -2,7 +2,6 @@
module test010; module test010;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
f : Nat → Nat → Nat f : Nat → Nat → Nat
| x := | x :=

View File

@ -2,7 +2,6 @@
module test012; module test012;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
pow0 : Nat := 1; pow0 : Nat := 1;

View File

@ -2,7 +2,6 @@
module test016; module test016;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
f : Nat → Nat → Nat f : Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module test020; module test020;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
f91 : Nat → Nat f91 : Nat → Nat

View File

@ -2,7 +2,6 @@
module test021; module test021;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
power' : Nat → Nat → Nat → Nat power' : Nat → Nat → Nat → Nat

View File

@ -2,11 +2,9 @@
module test022; module test022;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
f : Nat → Nat f : Nat → Nat
| x := if (x < 1) 1 (2 * x + g (sub x 1)); | x := if (x < 1) 1 (2 * x + g (sub x 1));
terminating terminating

View File

@ -2,7 +2,6 @@
module test023; module test023;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
gcd : Nat → Nat → Nat gcd : Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module test025; module test025;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
pow : Nat -> Nat pow : Nat -> Nat
| zero := 1 | zero := 1

View File

@ -2,7 +2,6 @@
module test026; module test026;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
sum : Nat → Nat := sum : Nat → Nat :=
let let

View File

@ -1,7 +1,6 @@
module test006; module test006;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
loop : Nat := loop; loop : Nat := loop;

View File

@ -1,7 +1,6 @@
module test011; module test011;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
fib' : Nat -> Nat -> Nat -> Nat fib' : Nat -> Nat -> Nat -> Nat
| zero x _ := x | zero x _ := x

View File

@ -1,7 +1,6 @@
module QuickSort; module QuickSort;
import Stdlib.Prelude open hiding {quickSort}; import Stdlib.Prelude open hiding {quickSort};
import Stdlib.Data.Nat.Ord open;
qsHelper : {A : Type} → A → List A × List A → List A qsHelper : {A : Type} → A → List A × List A → List A
| a (l, r) := l ++ (a :: nil) ++ r; | a (l, r) := l ++ (a :: nil) ++ r;
@ -40,6 +39,5 @@ four : Nat := suc three;
main : List Nat := main : List Nat :=
uniq uniq
compare Ord.cmp
(quickSort compare (flatten (gen2 three four nil))); (quickSort Ord.cmp (flatten (gen2 three four nil)));

View File

@ -1,7 +1,6 @@
module test001; module test001;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
{-# argnames: [a, b {-# argnames: [a, b
c] #-} c] #-}

View File

@ -2,7 +2,6 @@
module test001; module test001;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
main : Nat -> Nat main : Nat -> Nat
| x := if (x == 0) 1 0; | x := if (x == 0) 1 0;

View File

@ -2,7 +2,6 @@
module test002; module test002;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type optbool := type optbool :=
| Just : Bool -> optbool | Just : Bool -> optbool

View File

@ -2,7 +2,6 @@
module test003; module test003;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type enum := type enum :=
| opt0 : enum | opt0 : enum

View File

@ -2,7 +2,6 @@
module test006; module test006;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type enum := type enum :=
| opt0 : enum | opt0 : enum

View File

@ -2,7 +2,6 @@
module test008; module test008;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
f : Nat → Nat → Nat f : Nat → Nat → Nat
| x := | x :=

View File

@ -2,7 +2,6 @@
module test010; module test010;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
pow0 : Nat := 1; pow0 : Nat := 1;

View File

@ -2,7 +2,6 @@
module test017; module test017;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
{-# unroll: 11 #-} {-# unroll: 11 #-}
terminating terminating

View File

@ -2,7 +2,6 @@
module test018; module test018;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
pow : Nat -> Nat pow : Nat -> Nat
| zero := 1 | zero := 1

View File

@ -2,7 +2,6 @@
module test021; module test021;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
power : Nat → Nat → Nat := power : Nat → Nat → Nat :=
let let

View File

@ -2,7 +2,6 @@
module test022; module test022;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
power : Nat → Nat → Nat := power : Nat → Nat → Nat :=
let let

View File

@ -2,7 +2,6 @@
module test023; module test023;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
main : Nat → Nat → Nat main : Nat → Nat → Nat
| x y := | x y :=

View File

@ -2,7 +2,6 @@
module ackermann; module ackermann;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
iter : {A : Type} → (A → A) → Nat → A → A iter : {A : Type} → (A → A) → Nat → A → A
| f zero := id | f zero := id

View File

@ -2,7 +2,6 @@
module combinations; module combinations;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
terminating terminating
go : Nat → Nat → Nat go : Nat → Nat → Nat

View File

@ -2,7 +2,6 @@
module cps; module cps;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
step : Nat → Nat → Nat → (Nat → Nat → Nat → Nat) → Nat step : Nat → Nat → Nat → (Nat → Nat → Nat → Nat) → Nat
| zero n _ _ := n | zero n _ _ := n

View File

@ -2,7 +2,6 @@
module fibonacci; module fibonacci;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
go : Nat → Nat → Nat → Nat go : Nat → Nat → Nat → Nat
| zero n _ := n | zero n _ := n

View File

@ -2,7 +2,6 @@
module fold; module fold;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
plusMod : Nat → Nat → Nat plusMod : Nat → Nat → Nat
| x y := mod (x + y) 268435456; | x y := mod (x + y) 268435456;

View File

@ -2,7 +2,6 @@
module mapfold; module mapfold;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
run : Nat → Nat → List Nat → Nat run : Nat → Nat → List Nat → Nat
| zero acc lst := acc | zero acc lst := acc

View File

@ -2,7 +2,6 @@
module maybe; module maybe;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
type Tree := type Tree :=
| leaf : Tree | leaf : Tree

View File

@ -2,7 +2,6 @@
module mergesort; module mergesort;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
split_go split_go
: {A : Type} → List A → List A → List A → List A × List A : {A : Type} → List A → List A → List A → List A × List A

View File

@ -2,7 +2,6 @@
module prime; module prime;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
checkDivisible : Nat → List Nat → Bool checkDivisible : Nat → List Nat → Bool
| p nil := false | p nil := false

View File

@ -12,8 +12,6 @@ hiding -- Hide some names
-- Bool either -- Bool either
Bool; true; false; mkShow; module Show}; Bool; true; false; mkShow; module Show};
import Stdlib.Data.Nat.Ord open;
-- Lorem ipsum dolor sit amet, consectetur adipiscing elit -- Lorem ipsum dolor sit amet, consectetur adipiscing elit
terminating terminating
-- Comment between terminating and type sig -- Comment between terminating and type sig

View File

@ -1,7 +1,6 @@
module builtinTrace; module builtinTrace;
import Stdlib.Prelude open; import Stdlib.Prelude open;
import Stdlib.Data.Nat.Ord open;
builtin trace builtin trace
axiom trace : {A : Type} → A → A; axiom trace : {A : Type} → A → A;

View File

@ -62,6 +62,7 @@ tests:
- dev - dev
- core - core
- from-concrete - from-concrete
- -t eta-expand-apps
- --normalize - --normalize
args: args:
- positive/Internal/Norm.juvix - positive/Internal/Norm.juvix

View File

@ -74,11 +74,7 @@ tests:
stdin: ":def + (+) (((+)))" stdin: ":def + (+) (((+)))"
stdout: stdout:
contains: | contains: |
--- Addition for ;Nat;s. + {A} {{Natural A}} : A -> A -> A := Natural.+
builtin nat-plus
+ : Nat → Nat → Nat
| zero b := b
| (suc a) b := suc (a + b)
exit-status: 0 exit-status: 0
- name: repl-def-infix - name: repl-def-infix
@ -89,11 +85,7 @@ tests:
stdin: ":def +" stdin: ":def +"
stdout: stdout:
contains: | contains: |
--- Addition for ;Nat;s. + {A} {{Natural A}} : A -> A -> A := Natural.+
builtin nat-plus
+ : Nat → Nat → Nat
| zero b := b
| (suc a) b := suc (a + b)
exit-status: 0 exit-status: 0
- name: open - name: open
@ -454,7 +446,7 @@ tests:
command: command:
- juvix - juvix
- repl - repl
stdin: "import Stdlib.Data.Int.Ord as Int open\n1 == 1" stdin: "import Stdlib.Data.Int.Ord as Int open\n1 Int.== 1"
stdout: stdout:
contains: "true" contains: "true"
exit-status: 0 exit-status: 0
@ -463,9 +455,9 @@ tests:
command: command:
- juvix - juvix
- repl - repl
stdin: "import Stdlib.Data.Int.Ord open\n1 == 1" stdin: "import Stdlib.Data.Int.Ord open\ncompare 1 1"
stdout: stdout:
contains: "true" contains: "EQ"
exit-status: 0 exit-status: 0
- name: infix-constructors - name: infix-constructors