From 8ccbcce4d8c61efc0afd69f5ccb8cc78a233787e Mon Sep 17 00:00:00 2001
From: Michael Hanus <mh@informatik.uni-kiel.de>
Date: Fri, 18 Jun 2021 11:10:51 +0200
Subject: [PATCH] Tools updated

---
 cpm/src/CPM/ErrorLogger.curry                 |  4 +-
 cpm/src/CPM/FileUtil.curry                    | 15 ++--
 cpm/src/CPM/Main.curry                        | 78 ++++++++++---------
 cpm/src/CPM/PackageCache/Runtime.curry        | 65 ++++++++++++----
 .../src/Analysis/Deterministic.curry          | 11 ++-
 .../src/Analysis/HigherOrder.curry            |  6 +-
 .../src/System/Directory_external.go          |  4 +-
 cpm/vendor/global/src/Data/Global_external.go | 53 ++++++++++++-
 .../io-extra/src/System/IOExts_external.go    |  4 +-
 .../process/src/System/Process_external.go    |  2 +-
 cpm/vendor/profiling/package.json             |  5 +-
 .../profiling/src/Debug/Profile_external.go   | 63 +++++++++++++++
 .../read-legacy/src/ReadShowTerm_external.go  |  2 +-
 cpm/vendor/socket/src/Network/Socket.kics2    |  3 +-
 .../src/Analysis/Deterministic.curry          | 11 ++-
 .../src/Analysis/HigherOrder.curry            |  6 +-
 .../src/System/Directory_external.go          |  4 +-
 .../io-extra/src/System/IOExts_external.go    |  4 +-
 .../process/src/System/Process_external.go    |  2 +-
 .../read-legacy/src/ReadShowTerm_external.go  |  2 +-
 .../packages/socket/src/Network/Socket.kics2  |  3 +-
 optimize/LICENSE                              | 29 +++++++
 optimize/{README.txt => README.md}            | 11 ++-
 23 files changed, 292 insertions(+), 95 deletions(-)
 create mode 100644 cpm/vendor/profiling/src/Debug/Profile_external.go
 create mode 100644 optimize/LICENSE
 rename optimize/{README.txt => README.md} (72%)

diff --git a/cpm/src/CPM/ErrorLogger.curry b/cpm/src/CPM/ErrorLogger.curry
index 2ef1efae..b317368d 100644
--- a/cpm/src/CPM/ErrorLogger.curry
+++ b/cpm/src/CPM/ErrorLogger.curry
@@ -14,8 +14,8 @@ module CPM.ErrorLogger
   , inDirectoryEL, inTempDirEL
   ) where
 
-import System.IO      ( hPutStrLn, stderr )
-import System.Process ( exitWith, system )
+import System.IO        ( hPutStrLn, stderr )
+import System.Process   ( exitWith, system )
 import System.Directory
 
 import CPM.FileUtil
diff --git a/cpm/src/CPM/FileUtil.curry b/cpm/src/CPM/FileUtil.curry
index e67dee08..e90bd276 100644
--- a/cpm/src/CPM/FileUtil.curry
+++ b/cpm/src/CPM/FileUtil.curry
@@ -8,8 +8,7 @@ module CPM.FileUtil
   , copyDirectory
   , createSymlink
   , removeSymlink
-  , isSymlink
-  , linkTarget
+  , isSymlink, linkTarget, realPath
   , copyDirectoryFollowingSymlinks
   , quote
   , tempDir
@@ -76,9 +75,15 @@ isSymlink link = do
 linkTarget :: String -> IO String
 linkTarget link = do
   (rc, out, _) <- evalCmd "readlink" ["-n", link] ""
-  if rc == 0
-    then return $ replaceFileName link out
-    else return ""
+  return $ if rc == 0 then replaceFileName link out
+                      else ""
+
+--- Returns the real path for a given file path by following all symlinks
+--- in all path components.
+realPath :: String -> IO String
+realPath path = do
+  (rc, out, _) <- evalCmd "readlink" ["-fn", path] ""
+  return $ if rc == 0 then out else path
 
 --- Puts a file argument into quotes to avoid problems with files containing
 --- blanks.
diff --git a/cpm/src/CPM/Main.curry b/cpm/src/CPM/Main.curry
index 063d8f9e..7ba9467a 100644
--- a/cpm/src/CPM/Main.curry
+++ b/cpm/src/CPM/Main.curry
@@ -67,7 +67,7 @@ cpmBanner = unlines [bannerLine, bannerText, bannerLine]
  where
   bannerText =
     "Curry Package Manager <curry-lang.org/tools/cpm> (Version " ++
-    packageVersion ++ ", 31/05/2021)"
+    packageVersion ++ ", 18/06/2021)"
   bannerLine = take (length bannerText) (repeat '-')
 
 main :: IO ()
@@ -102,6 +102,9 @@ runWithArgs opts = do
       logDebug $ "Current configuration:\n" ++ showConfiguration config
       case optCommand opts of
         NoCommand   -> fail "NoCommand"
+        Help        -> liftIOEL $ do
+                         putStrLn cpmBanner
+                         printUsage "cypm" 80 (optionParser [])
         Config o    -> configCmd    o config
         Update o    -> updateCmd    o config
         Compiler o  -> curryCmd     o config
@@ -144,6 +147,7 @@ defaultOptions = Options Info [] False False NoCommand
 
 data Command
   = NoCommand
+  | Help
   | Config     ConfigOptions
   | Deps       DepsOptions
   | Checkout   CheckoutOptions
@@ -424,64 +428,66 @@ optionParser allargs = optParser
         <> short "t"
         <> help "Show elapsed time with every log output" )
   <.> commands (metavar "COMMAND")
-        (   command "config"
-                    (help "Show current configuration of CPM")
-                    (\a -> Right $ a { optCommand = Config (configOpts a) })
-                    configArgs
+        (   command "add"
+              (help "Add a package (as dependency or to the local repository)")
+              Right
+              addArgs
         <|> command "checkout" (help "Checkout a package.") Right
                     (checkoutArgs Checkout)
-        <|> command "install" (help "Install a package with its dependencies.")
-                     (\a -> Right $ a { optCommand = Install (installOpts a) })
-                     installArgs
-        <|> command "uninstall" (help "Uninstall a package")
-                 (\a -> Right $ a { optCommand = Uninstall (uninstallOpts a) })
-                 uninstallArgs
-        <|> command "deps" (help "Calculate dependencies")
-                           (\a -> Right $ a { optCommand = Deps (depsOpts a) })
-                           depsArgs
         <|> command "clean" (help "Clean the current package")
                             (\a -> Right $ a { optCommand = Clean }) []
-        <|> command "new" (help "Create a new package") Right newArgs
-        <|> command "update"
-                    (help "Update the package index")
-                    (\a -> Right $ a { optCommand = Update (updateOpts a) })
-                    updateArgs
+        <|>  command "config"
+                    (help "Show current configuration of CPM")
+                    (\a -> Right $ a { optCommand = Config (configOpts a) })
+                    configArgs
         <|> command "curry"
            (help "Load package spec and start Curry with correct dependencies.")
                  (\a -> Right $ a { optCommand = Compiler (execOpts a) })
                  curryArgs
+        <|> command "deps" (help "Calculate dependencies")
+                           (\a -> Right $ a { optCommand = Deps (depsOpts a) })
+                           depsArgs
+        <|> command "diff"
+                    (help "Diff the current package against another version")
+                    (\a -> Right $ a { optCommand = Diff (diffOpts a) })
+                    diffArgs
+        <|> command "doc"
+           (help "Generation documentation for current package (with CurryDoc)")
+                    (\a -> Right $ a { optCommand = Doc (docOpts a) })
+                    docArgs
         <|> command "exec"
                     (help "Execute a command with the CURRYPATH set")
                     (\a -> Right $ a { optCommand = Exec (execOpts a) })
                     execArgs
+        <|> command "help" (help "Show list of all commands and quit")
+                           (\a -> Right $ a { optCommand = Help }) []
         <|> command "info" (help "Print package information")
                     (\a -> Right $ a { optCommand = PkgInfo (infoOpts a) })
                     infoArgs
-        <|> command "doc"
-           (help "Generation documentation for current package (with CurryDoc)")
-                    (\a -> Right $ a { optCommand = Doc (docOpts a) })
-                    docArgs
-        <|> command "test" (help "Test the current package (with CurryCheck)")
-                    (\a -> Right $ a { optCommand = Test (testOpts a) })
-                    testArgs
-        <|> command "diff"
-                    (help "Diff the current package against another version")
-                    (\a -> Right $ a { optCommand = Diff (diffOpts a) })
-                    diffArgs
+        <|> command "install" (help "Install a package with its dependencies.")
+                     (\a -> Right $ a { optCommand = Install (installOpts a) })
+                     installArgs
+        <|> command "link" (help "Link a package to the local cache") Right
+                    linkArgs
         <|> command "list" (help "List all packages of the repository")
                     (\a -> Right $ a { optCommand = List (listOpts a) })
                     listArgs
+        <|> command "new" (help "Create a new package") Right newArgs
         <|> command "search" (help "Search the package repository") Right
                     searchArgs
+        <|> command "test" (help "Test the current package (with CurryCheck)")
+                    (\a -> Right $ a { optCommand = Test (testOpts a) })
+                    testArgs
+        <|> command "uninstall" (help "Uninstall a package")
+                 (\a -> Right $ a { optCommand = Uninstall (uninstallOpts a) })
+                 uninstallArgs
         <|> command "upgrade" (help "Upgrade one or more packages")
                     (\a -> Right $ a { optCommand = Upgrade (upgradeOpts a) })
                     upgradeArgs
-        <|> command "link" (help "Link a package to the local cache") Right
-                    linkArgs
-        <|> command "add"
-              (help "Add a package (as dependency or to the local repository)")
-              Right
-              addArgs
+        <|> command "update"
+                    (help "Update the package index")
+                    (\a -> Right $ a { optCommand = Update (updateOpts a) })
+                    updateArgs
         <|> command "upload"
                     (help "Upload current package to package server")
                     (\a -> Right $ a { optCommand = Upload (uploadOpts a) })
diff --git a/cpm/src/CPM/PackageCache/Runtime.curry b/cpm/src/CPM/PackageCache/Runtime.curry
index fcf19877..35d3f250 100644
--- a/cpm/src/CPM/PackageCache/Runtime.curry
+++ b/cpm/src/CPM/PackageCache/Runtime.curry
@@ -10,11 +10,11 @@ module CPM.PackageCache.Runtime
   , writePackageConfig
   ) where
 
-import System.FilePath    ( (</>), (<.>), takeDirectory )
+import Data.List          ( intercalate, isPrefixOf, split )
 import System.Directory   ( createDirectoryIfMissing, copyFile, doesFileExist
                           , getDirectoryContents, doesDirectoryExist
                           , getAbsolutePath )
-import Data.List          ( intercalate, split )
+import System.FilePath    ( (</>), (<.>), splitSearchPath, takeDirectory )
 
 import CPM.Config         ( Config, binInstallDir )
 import CPM.ErrorLogger
@@ -22,7 +22,8 @@ import CPM.PackageCache.Global (installedPackageDir)
 import CPM.Package        ( Package, packageId, PackageExecutable(..)
                           , sourceDirsOf, executableSpec, version
                           , configModule, showVersion )
-import CPM.FileUtil       ( copyDirectoryFollowingSymlinks, recreateDirectory )
+import CPM.FileUtil       ( copyDirectoryFollowingSymlinks, realPath
+                          , recreateDirectory )
 import CPM.PackageCache.Local as LocalCache
 import CPM.Repository     ( readPackageFromRepository )
 
@@ -82,12 +83,14 @@ writePackageConfig :: Config -> String -> Package -> String -> ErrorLogger ()
 writePackageConfig cfg pkgdir pkg loadpath =
   maybe (return ())
         (\configmod ->
-           let binnames = map (\ (PackageExecutable n _ _) -> n)
-                              (executableSpec pkg)
-           in if null configmod
-                then return ()
-                else do writeConfigFile configmod binnames
-                        return ())
+           if null configmod
+             then return ()
+             else do
+               let binnames = map (\ (PackageExecutable n _ _) -> n)
+                                  (executableSpec pkg)
+               realbins <- mapM (liftIOEL . realPath . (binInstallDir cfg </>))
+                                binnames
+               writeConfigFile configmod realbins)
         (configModule pkg)
  where
   writeConfigFile configmod binnames = do
@@ -103,27 +106,55 @@ writePackageConfig cfg pkgdir pkg loadpath =
         , "packageVersion :: String"
         , "packageVersion = \"" ++ showVersion (version pkg) ++ "\""
         , ""
-        , "--- Package location."
+        , "--- Returns the location (installation directory) of the package."
+        , "getPackagePath :: IO String"
+        , "getPackagePath = return " ++ show abspkgdir
+        , ""
+        , "--- Package location (deprecated, use 'getPackagePath')."
         , "packagePath :: String"
         , "packagePath = " ++ show abspkgdir
         , ""
-        , "--- Load path for the package (if it is the main package)."
+        , "--- Returns the load path for the package (if it is the main package)."
+        , "getPackageLoadPath :: IO [String]"
+        , "getPackageLoadPath = do"
+        , "  pp <- getPackagePath"
+        , "  return " ++ showLoadPath abspkgdir
+        , ""
+        , "--- Load path for the package (deprecated, use 'getPackageLoadPath')."
         , "packageLoadPath :: String"
         , "packageLoadPath = " ++ show loadpath
         , "" ] ++
         showExecutables binnames
     logDebug $ "Config module '" ++ configfile ++ "' written."
 
+  showLoadPath pdir =
+    "[" ++
+    intercalate ", "
+      (map replacePackagePath
+        (splitSearchPath loadpath)) ++ "]"
+   where
+    replacePackagePath d =
+      if pdir `isPrefixOf` d
+        then "pp ++ " ++ show (drop (length pdir) d)
+        else show d
+
   showExecutables bins = case length bins of
     0 -> []
-    1 -> [ "--- Location of the executable installed by this package."
+    1 -> [ "--- Returns the location of the executable installed by this package."
+         , "getPackageExecutable :: IO String"
+         , "getPackageExecutable = return \"" ++ head bins ++ "\""
+         , ""
+         , "--- Location of the executable (deprecated, use 'getPackageExecutable')."
          , "packageExecutable :: String"
-         , "packageExecutable = \"" ++ binInstallDir cfg </> head bins ++ "\""
+         , "packageExecutable = \"" ++ head bins ++ "\""
          ]
-    _ -> [ "--- Location of the executables installed by this package."
+    _ -> [ "--- Returns the locations of the executables installed by this package."
+         , "getPackageExecutables :: IO [String]"
+         , "getPackageExecutables = return [" ++
+           intercalate ", " (map (\s -> "\"" ++ s ++ "\"") bins) ++ "]"
+         , ""
+         , "--- Location of the executables (deprecated, use 'getPackageExecutables')."
          , "packageExecutables :: [String]"
          , "packageExecutables = [" ++
-           intercalate ", "
-             (map (\s -> "\"" ++ binInstallDir cfg </> s ++ "\"") bins) ++
-           "]"
+           intercalate ", " (map (\s -> "\"" ++ s ++ "\"") bins) ++ "]"
          ]
diff --git a/cpm/vendor/cass-analysis/src/Analysis/Deterministic.curry b/cpm/vendor/cass-analysis/src/Analysis/Deterministic.curry
index 72792772..0ed93358 100644
--- a/cpm/vendor/cass-analysis/src/Analysis/Deterministic.curry
+++ b/cpm/vendor/cass-analysis/src/Analysis/Deterministic.curry
@@ -102,7 +102,7 @@ extraVarInExpr (Typed e _) = extraVarInExpr e
 -- It assigns to a function a flag which indicates whether is function
 -- might be non-deterministic, i.e., might reduce in different ways
 -- for given ground arguments.
--- If the non-determinism is encapsulated (set functions, AllSolutions),
+-- If the non-determinism is encapsulated (set functions, getAllValues),
 -- it is classified as deterministic.
 
 --- Data type to represent determinism information.
@@ -144,13 +144,18 @@ nondetFunc func@(Func _ _ _ _ rule) calledFuncs =
       -- its called ND functions are not relevant:
       if null es then False -- this case should not occur
                  else any callsNDOp (tail es)
-    | mn == "AllSolutions" -- && fn `elem`== "getAllValues"
+    | isStrongEncapsOp qf
     = -- non-determinism of argument is encapsulated so that
       -- its called ND functions are not relevant:
       False
     | otherwise
     = maybe False (==NDet) (lookup qf calledFuncs) || any callsNDOp es
 
+-- Does the operation ensures the strong encapsulation of its argument?
+isStrongEncapsOp :: QName -> Bool
+isStrongEncapsOp (mn,_) =
+  mn `elem` ["Control.AllSolutions", "Control.AllValues"]
+
 ------------------------------------------------------------------------------
 --- Data type to represent information about non-deterministic dependencies.
 --- Basically, it is the set (represented as a sorted list) of
@@ -236,7 +241,7 @@ nondetDeps alldeps func@(Func f _ _ _ rule) calledFuncs =
       -- its called ND functions are not relevant:
       if null es then [] -- this case should not occur
                  else concatMap calledNDFuncs (tail es)
-    | mn == "AllSolutions" -- && fn `elem`== "getAllValues"
+    | isStrongEncapsOp qf
     = -- non-determinism of argument is encapsulated so that
       -- its called ND functions are not relevant:
       []
diff --git a/cpm/vendor/cass-analysis/src/Analysis/HigherOrder.curry b/cpm/vendor/cass-analysis/src/Analysis/HigherOrder.curry
index f620544a..afbdd62a 100644
--- a/cpm/vendor/cass-analysis/src/Analysis/HigherOrder.curry
+++ b/cpm/vendor/cass-analysis/src/Analysis/HigherOrder.curry
@@ -81,11 +81,11 @@ orderOfFuncTypeArity orderMap functype arity =
   then
    case functype of
      FuncType _ _   -> HO
-     TVar (-42)     -> HO
+     TVar tv        -> if tv == (-42) then HO else FO
      TCons x (y:ys) -> hoOr (orderOfFuncTypeArity orderMap y 0)
                             (orderOfFuncTypeArity orderMap (TCons x ys) 0)
-     TCons tc [] -> fromMaybe FO (lookupProgInfo tc orderMap)
-     _ -> FO
+     TCons tc []    -> fromMaybe FO (lookupProgInfo tc orderMap)
+     _              -> FO
   else let (FuncType x y) = functype
         in hoOr (orderOfFuncTypeArity orderMap x 0)
                 (orderOfFuncTypeArity orderMap y (arity-1))
diff --git a/cpm/vendor/directory/src/System/Directory_external.go b/cpm/vendor/directory/src/System/Directory_external.go
index 5facf119..0de2fb9f 100644
--- a/cpm/vendor/directory/src/System/Directory_external.go
+++ b/cpm/vendor/directory/src/System/Directory_external.go
@@ -2,8 +2,8 @@ package SystemDirectory
 
 import "gocurry"
 import "os"
-import "../../Prelude"
-import "../../Data/Time"
+import "curry2go/Prelude"
+import "curry2go/Data/Time"
 
 func ExternalSystem_Directory_prim_doesFileExist(task *gocurry.Task){
     root := task.GetControl()
diff --git a/cpm/vendor/global/src/Data/Global_external.go b/cpm/vendor/global/src/Data/Global_external.go
index 9c2f3a32..7e9ba12a 100644
--- a/cpm/vendor/global/src/Data/Global_external.go
+++ b/cpm/vendor/global/src/Data/Global_external.go
@@ -1,17 +1,64 @@
 package DataGlobal
 
 import "gocurry"
+import "curry2go/Prelude"
 
+var global_map = make(map[string]*gocurry.Node)
+var func_name = "arg_eval"
 
 func ExternalData_Global_prim_globalT(task *gocurry.Task){
-    panic("Data.Global.globalT: not yet implemented")
+    root := task.GetControl()
+    curry_name := root.GetChild(0)
+    value := root.GetChild(1)
+    name := gocurry.ReadString(curry_name)
+    
+    // test if an entry already exists
+    _, ok := global_map[name]
+    
+    // initialize the entry
+    if !ok{
+        value = Prelude.Prelude__CREATE_DolHashHash(root.NewNode(), Prelude.Prelude__CREATE_id(root.NewNode()), value)
+        global_map[name] = value
+        
+        // evaluate the entry
+        gocurry.FuncCreate(root, func(task *gocurry.Task){
+            DataGlobal__CREATE_GlobalT(task.GetControl(), curry_name)
+        }, &func_name, 1, 0, value)
+        return
+    }
+    
+    // return GlobalT
+    DataGlobal__CREATE_GlobalT(root, curry_name)
 }
 
 func ExternalData_Global_prim_readGlobalT(task *gocurry.Task){
-    panic("Data.Global.readGlobalT: not yet implemented")
+    root := task.GetControl()
+    global := root.GetChild(0)
+    curry_name := global.GetChild(0)
+    name := gocurry.ReadString(curry_name)
+    
+    // retrieve the value
+    value, ok := global_map[name]
+    
+    if !ok{
+        panic("Data.Global.readGlobalT: read on uninitialized entry '" + name + "'")
+    }
+    
+    // return the value
+    gocurry.IOCreate(root, value)
 }
 
 func ExternalData_Global_prim_writeGlobalT(task *gocurry.Task){
-    panic("Data.Global.writeGlobalT: not yet implemented")
+    root := task.GetControl()
+    global := root.GetChild(0)
+    curry_name := global.GetChild(0)
+    name := gocurry.ReadString(curry_name)
+    value := root.GetChild(1)
+    
+    // set entry to value
+    global_map[name] = value
+    
+    // return
+    gocurry.IOCreate(root, Prelude.Prelude__CREATE_LbRb(root.NewNode()))
 }
 
diff --git a/cpm/vendor/io-extra/src/System/IOExts_external.go b/cpm/vendor/io-extra/src/System/IOExts_external.go
index 86ec7af1..5b338c02 100644
--- a/cpm/vendor/io-extra/src/System/IOExts_external.go
+++ b/cpm/vendor/io-extra/src/System/IOExts_external.go
@@ -1,8 +1,8 @@
 package SystemIOExts
 
 import "gocurry"
-import "../IO"
-import "../../Prelude"
+import "curry2go/System/IO"
+import "curry2go/Prelude"
 import "os/exec"
 
 
diff --git a/cpm/vendor/process/src/System/Process_external.go b/cpm/vendor/process/src/System/Process_external.go
index 35ab27dc..44fbddbf 100644
--- a/cpm/vendor/process/src/System/Process_external.go
+++ b/cpm/vendor/process/src/System/Process_external.go
@@ -5,7 +5,7 @@ import "os"
 import "os/exec"
 import "time"
 import "fmt"
-import "../../Prelude"
+import "curry2go/Prelude"
 
 func ExternalSystem_Process_getPID(task *gocurry.Task){
     root := task.GetControl()
diff --git a/cpm/vendor/profiling/package.json b/cpm/vendor/profiling/package.json
index d81c7dba..06dafb99 100644
--- a/cpm/vendor/profiling/package.json
+++ b/cpm/vendor/profiling/package.json
@@ -10,8 +10,9 @@
         "base" : ">= 3.0.0, < 4.0.0"
     },
     "compilerCompatibility": {
-        "pakcs": ">= 3.0.0, < 4.0.0",
-        "kics2": ">= 3.0.0, < 4.0.0"
+        "pakcs"   : ">= 3.0.0, < 4.0.0",
+        "kics2"   : ">= 3.0.0, < 4.0.0",
+        "curry2go": ">= 1.0.0"
     },
     "exportedModules": [ "Debug.Profile" ],
     "source": {
diff --git a/cpm/vendor/profiling/src/Debug/Profile_external.go b/cpm/vendor/profiling/src/Debug/Profile_external.go
new file mode 100644
index 00000000..ceeae473
--- /dev/null
+++ b/cpm/vendor/profiling/src/Debug/Profile_external.go
@@ -0,0 +1,63 @@
+package DebugProfile
+
+import "gocurry"
+import "runtime"
+import "runtime/debug"
+import "curry2go/Prelude"
+
+
+func ExternalDebug_Profile_getProcessInfos(task *gocurry.Task){
+    root := task.GetControl()
+    
+    // get elapsed time
+    elapsed := gocurry.IntLitCreate(root.NewNode(), int(gocurry.Uptime().Milliseconds()))
+    elapsed_node := Prelude.Prelude__CREATE_LbCommaRb(root.NewNode(), DebugProfile__CREATE_ElapsedTime(root.NewNode()), elapsed)
+    
+    // get MemStats
+    mem_stats := new(runtime.MemStats)
+    runtime.ReadMemStats(mem_stats)
+    
+    // get total memory
+    sys := gocurry.IntLitCreate(root.NewNode(), int(mem_stats.Sys))
+    sys_node := Prelude.Prelude__CREATE_LbCommaRb(root.NewNode(), DebugProfile__CREATE_Memory(root.NewNode()), sys)
+    
+    // get stack memory
+    stack := gocurry.IntLitCreate(root.NewNode(), int(mem_stats.StackSys))
+    stack_node := Prelude.Prelude__CREATE_LbCommaRb(root.NewNode(), DebugProfile__CREATE_Stack(root.NewNode()), stack)
+    
+    // get heap memory
+    heap := gocurry.IntLitCreate(root.NewNode(), int(mem_stats.HeapAlloc))
+    heap_node := Prelude.Prelude__CREATE_LbCommaRb(root.NewNode(), DebugProfile__CREATE_Heap(root.NewNode()), heap)
+    
+    // get garbage collection count
+    gc := gocurry.IntLitCreate(root.NewNode(), int(mem_stats.NumGC))
+    gc_node := Prelude.Prelude__CREATE_LbCommaRb(root.NewNode(), DebugProfile__CREATE_GarbageCollections(root.NewNode()), gc)
+    
+    // return
+    list := Prelude.ListCreate(root.NewNode(), elapsed_node, sys_node, stack_node, heap_node, gc_node)
+    gocurry.IOCreate(root, list)
+}
+
+func ExternalDebug_Profile_garbageCollectorOff(task *gocurry.Task){
+    root := task.GetControl()
+    
+    debug.SetGCPercent(-1)
+    
+    gocurry.IOCreate(root, Prelude.Prelude__CREATE_LbRb(root.NewNode()))
+}
+
+func ExternalDebug_Profile_garbageCollectorOn(task *gocurry.Task){
+    root := task.GetControl()
+    
+    debug.SetGCPercent(100)
+    
+    gocurry.IOCreate(root, Prelude.Prelude__CREATE_LbRb(root.NewNode()))
+}
+
+func ExternalDebug_Profile_garbageCollect(task *gocurry.Task){
+    root := task.GetControl()
+    
+    runtime.GC()
+    
+    gocurry.IOCreate(root, Prelude.Prelude__CREATE_LbRb(root.NewNode()))
+}
diff --git a/cpm/vendor/read-legacy/src/ReadShowTerm_external.go b/cpm/vendor/read-legacy/src/ReadShowTerm_external.go
index e53c2e6d..c5909238 100644
--- a/cpm/vendor/read-legacy/src/ReadShowTerm_external.go
+++ b/cpm/vendor/read-legacy/src/ReadShowTerm_external.go
@@ -4,7 +4,7 @@ import "strings"
 import "runtime"
 import "gocurry"
 import "path/filepath"
-import "../Prelude"
+import "curry2go/Prelude"
 
 func ExternalReadShowTerm_prim_showTerm(task *gocurry.Task){
     root := task.GetControl()
diff --git a/cpm/vendor/socket/src/Network/Socket.kics2 b/cpm/vendor/socket/src/Network/Socket.kics2
index 4e43f235..6c841e3c 100644
--- a/cpm/vendor/socket/src/Network/Socket.kics2
+++ b/cpm/vendor/socket/src/Network/Socket.kics2
@@ -49,8 +49,7 @@ listenOn pn = do
   addr:_ <- getAddrInfo (Just hints) Nothing (Just (show pn))
   sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
   setSocketOption sock ReuseAddr 1
-  fd <- fdSocket sock
-  setCloseOnExecIfNeeded fd
+  withFdSocket sock setCloseOnExecIfNeeded
   Network.Socket.bind sock (addrAddress addr)
   listen sock maxListenQueue
   return sock
diff --git a/optimize/.cpm/packages/cass-analysis/src/Analysis/Deterministic.curry b/optimize/.cpm/packages/cass-analysis/src/Analysis/Deterministic.curry
index 72792772..0ed93358 100644
--- a/optimize/.cpm/packages/cass-analysis/src/Analysis/Deterministic.curry
+++ b/optimize/.cpm/packages/cass-analysis/src/Analysis/Deterministic.curry
@@ -102,7 +102,7 @@ extraVarInExpr (Typed e _) = extraVarInExpr e
 -- It assigns to a function a flag which indicates whether is function
 -- might be non-deterministic, i.e., might reduce in different ways
 -- for given ground arguments.
--- If the non-determinism is encapsulated (set functions, AllSolutions),
+-- If the non-determinism is encapsulated (set functions, getAllValues),
 -- it is classified as deterministic.
 
 --- Data type to represent determinism information.
@@ -144,13 +144,18 @@ nondetFunc func@(Func _ _ _ _ rule) calledFuncs =
       -- its called ND functions are not relevant:
       if null es then False -- this case should not occur
                  else any callsNDOp (tail es)
-    | mn == "AllSolutions" -- && fn `elem`== "getAllValues"
+    | isStrongEncapsOp qf
     = -- non-determinism of argument is encapsulated so that
       -- its called ND functions are not relevant:
       False
     | otherwise
     = maybe False (==NDet) (lookup qf calledFuncs) || any callsNDOp es
 
+-- Does the operation ensures the strong encapsulation of its argument?
+isStrongEncapsOp :: QName -> Bool
+isStrongEncapsOp (mn,_) =
+  mn `elem` ["Control.AllSolutions", "Control.AllValues"]
+
 ------------------------------------------------------------------------------
 --- Data type to represent information about non-deterministic dependencies.
 --- Basically, it is the set (represented as a sorted list) of
@@ -236,7 +241,7 @@ nondetDeps alldeps func@(Func f _ _ _ rule) calledFuncs =
       -- its called ND functions are not relevant:
       if null es then [] -- this case should not occur
                  else concatMap calledNDFuncs (tail es)
-    | mn == "AllSolutions" -- && fn `elem`== "getAllValues"
+    | isStrongEncapsOp qf
     = -- non-determinism of argument is encapsulated so that
       -- its called ND functions are not relevant:
       []
diff --git a/optimize/.cpm/packages/cass-analysis/src/Analysis/HigherOrder.curry b/optimize/.cpm/packages/cass-analysis/src/Analysis/HigherOrder.curry
index f620544a..afbdd62a 100644
--- a/optimize/.cpm/packages/cass-analysis/src/Analysis/HigherOrder.curry
+++ b/optimize/.cpm/packages/cass-analysis/src/Analysis/HigherOrder.curry
@@ -81,11 +81,11 @@ orderOfFuncTypeArity orderMap functype arity =
   then
    case functype of
      FuncType _ _   -> HO
-     TVar (-42)     -> HO
+     TVar tv        -> if tv == (-42) then HO else FO
      TCons x (y:ys) -> hoOr (orderOfFuncTypeArity orderMap y 0)
                             (orderOfFuncTypeArity orderMap (TCons x ys) 0)
-     TCons tc [] -> fromMaybe FO (lookupProgInfo tc orderMap)
-     _ -> FO
+     TCons tc []    -> fromMaybe FO (lookupProgInfo tc orderMap)
+     _              -> FO
   else let (FuncType x y) = functype
         in hoOr (orderOfFuncTypeArity orderMap x 0)
                 (orderOfFuncTypeArity orderMap y (arity-1))
diff --git a/optimize/.cpm/packages/directory/src/System/Directory_external.go b/optimize/.cpm/packages/directory/src/System/Directory_external.go
index 5facf119..0de2fb9f 100644
--- a/optimize/.cpm/packages/directory/src/System/Directory_external.go
+++ b/optimize/.cpm/packages/directory/src/System/Directory_external.go
@@ -2,8 +2,8 @@ package SystemDirectory
 
 import "gocurry"
 import "os"
-import "../../Prelude"
-import "../../Data/Time"
+import "curry2go/Prelude"
+import "curry2go/Data/Time"
 
 func ExternalSystem_Directory_prim_doesFileExist(task *gocurry.Task){
     root := task.GetControl()
diff --git a/optimize/.cpm/packages/io-extra/src/System/IOExts_external.go b/optimize/.cpm/packages/io-extra/src/System/IOExts_external.go
index 86ec7af1..5b338c02 100644
--- a/optimize/.cpm/packages/io-extra/src/System/IOExts_external.go
+++ b/optimize/.cpm/packages/io-extra/src/System/IOExts_external.go
@@ -1,8 +1,8 @@
 package SystemIOExts
 
 import "gocurry"
-import "../IO"
-import "../../Prelude"
+import "curry2go/System/IO"
+import "curry2go/Prelude"
 import "os/exec"
 
 
diff --git a/optimize/.cpm/packages/process/src/System/Process_external.go b/optimize/.cpm/packages/process/src/System/Process_external.go
index 35ab27dc..44fbddbf 100644
--- a/optimize/.cpm/packages/process/src/System/Process_external.go
+++ b/optimize/.cpm/packages/process/src/System/Process_external.go
@@ -5,7 +5,7 @@ import "os"
 import "os/exec"
 import "time"
 import "fmt"
-import "../../Prelude"
+import "curry2go/Prelude"
 
 func ExternalSystem_Process_getPID(task *gocurry.Task){
     root := task.GetControl()
diff --git a/optimize/.cpm/packages/read-legacy/src/ReadShowTerm_external.go b/optimize/.cpm/packages/read-legacy/src/ReadShowTerm_external.go
index e53c2e6d..c5909238 100644
--- a/optimize/.cpm/packages/read-legacy/src/ReadShowTerm_external.go
+++ b/optimize/.cpm/packages/read-legacy/src/ReadShowTerm_external.go
@@ -4,7 +4,7 @@ import "strings"
 import "runtime"
 import "gocurry"
 import "path/filepath"
-import "../Prelude"
+import "curry2go/Prelude"
 
 func ExternalReadShowTerm_prim_showTerm(task *gocurry.Task){
     root := task.GetControl()
diff --git a/optimize/.cpm/packages/socket/src/Network/Socket.kics2 b/optimize/.cpm/packages/socket/src/Network/Socket.kics2
index 4e43f235..6c841e3c 100644
--- a/optimize/.cpm/packages/socket/src/Network/Socket.kics2
+++ b/optimize/.cpm/packages/socket/src/Network/Socket.kics2
@@ -49,8 +49,7 @@ listenOn pn = do
   addr:_ <- getAddrInfo (Just hints) Nothing (Just (show pn))
   sock <- socket (addrFamily addr) (addrSocketType addr) (addrProtocol addr)
   setSocketOption sock ReuseAddr 1
-  fd <- fdSocket sock
-  setCloseOnExecIfNeeded fd
+  withFdSocket sock setCloseOnExecIfNeeded
   Network.Socket.bind sock (addrAddress addr)
   listen sock maxListenQueue
   return sock
diff --git a/optimize/LICENSE b/optimize/LICENSE
new file mode 100644
index 00000000..5135e06a
--- /dev/null
+++ b/optimize/LICENSE
@@ -0,0 +1,29 @@
+Copyright (c) 2021, Michael Hanus
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the distribution.
+
+3. Neither the names of the copyright holders nor the names of its
+   contributors may be used to endorse or promote products derived from
+   this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/optimize/README.txt b/optimize/README.md
similarity index 72%
rename from optimize/README.txt
rename to optimize/README.md
index 34f379ec..a17d49cf 100644
--- a/optimize/README.txt
+++ b/optimize/README.md
@@ -1,15 +1,22 @@
+transbooleq: A tool to transform Boolean equalities into constraints
+====================================================================
+
 This package contains the implementation of a transformation tool
 that replaces Boolean equalities by equational constraints
 in FlatCurry programs.
 
 The tool is integrated into the compilation chain of PAKCS/KiCS2.
-The motivation and ideas of this tool are described in the following paper:
+The motivation and ideas of this tool are described in the following papers:
 
 Antoy, S., Hanus, M.: From Boolean Equalities to Constraints
 Proceedings of the 25th International Symposium on Logic-based Program
-Synthesis and Transformation (LOPSTR 2015), Springer LNCS 9527, 2015, 73-88
+Synthesis and Transformation (LOPSTR 2015), Springer LNCS 9527, 2015, pp. 73-88
 http://dx.doi.org/10.1007/978-3-319-27436-2_5
 
+Antoy, S., Hanus, M.: Transforming Boolean equalities into constraints
+Formal Aspects of Computing, 29(3), 2017, pp. 475-494
+http://dx.doi.org/10.1007/s00165-016-0399-6
+
 
 Statistics about the number of transformations are shown
 with increased verbosity levels. For instance, if one sets the
-- 
GitLab