Home
_______ _______ __ _ ______ |______ | |______ | \ | | ____ | |_____ |______ | \_| |_____| Version: 10 This software is an implementation of "FLENG", a low level concurrent logic programming language descended from Prolog. A compiler is provided to translate programs written in FLENG into assembly" language which can subsequently be compiled and linked into a binary executable. As FLENG is quite minimal in features, a translator from "Flat Guarded Horn Clauses" or "Strand" (other concurrent logic languages) into FLENG is also available. FLENG programs allow for massive parallelism at a very fine grained level - goals are executed concurrently and communicate solely via single-assignment logic variables. The use of logic variables for inter-process communication offers an easy to use and convenient abstraction to implement many common patterns of synchronization and message passing in a natural manner. This implementation additionally can distribute pools of parallel processes over native OS level threads, thus taking advantage of multicore architectures. Locking overhead should be small, as data is normally not shared among processes executing on different threads. Automatic management of memory is provided using a reference-counting scheme of fixed size cells, which avoid fragmentation, eliminates garbage collection pauses and keeps the overall memory required to hold live data at any point of time minimal, while providing relatively good locality. Interfacing to native code is straightforward and compiled FLENG code and the run time library support can be linked with other modules written in C or C++ without problems. The compilation tools allow cross compilation, provided the architecture is supported. The compiler generates native code, but does currently not perform a lot of optimizations, so performance-sensitive code should probably be written in C or another language. FLENG should be particularly well suited as a coordination language for providing intercommunication and synchronization with reasonable overhead while calling out to C or C++ code for low-level or speed-critical operations. Suggestions for improvement or patches providing enhancements and corrections are very welcome, see the User's manual for information on how to contact the author. Also check out the "#fleng" IRC channel on https://Libera.chat if you have questions or need assistance. This software was written by Felix L. Winkelmann and has been released into the public domain. Do with it whatever you like. Installation instructions
User's Manual
Get the code
Release History: Version 10: * The system has been ported to MacOS on M1 CPUs. * Ordering guards ("@>", "@<", "@>=" and "@=<") now suspend on unbound variables, as in Strand. * Removed computation types "@<", and "@>" for "compute/4". * The conditional operator handles conjunctions of guards in the condition position. * Calls to the internal matching primitive didn't preserve the argument registers which could result in a memory leak. * Fixed a bug in the scheduler related to idle-suspensions, which could result in an assertion being thrown. * Argument pair expansion is handled in conditional expressions properly. * Added "global/2". * The "include/1" declaration accepts lists and doesn't require a file extension. * Added "arguments/1" declaration which allows defining run-time command line arguments at compile-time. * Removed the "threads" declaration, use "-arguments('+THREADS <N>')" instead. * Uses saved program states for the FGHC and FLENG compilers when SWI Prolog is used, which needs fewer files to install and speed up startup of the compilers. * Inlining of simple predicates is now done. * Calls to standard libraries provided by the base system are now faster by using predefined "entry-point" information. * Added compiler options "-e" and "-link" to create and use entry-point information in user code. * "app" module: added "any/3", "every/3" and "sequence/{4,5}". * Most higher-order predicates from the "app" module are now expanded in-line to avoid dynamic goal lookup and invocation. * Obviously circular variable references in assignments and unifications generate a compile-time error now. * "list" module: added "last/2", "delete/3", "prefix/3" and "reverse/{2,3}". * "io" module: added "write_lines/3". * "mem" module: added "copy/{4,5,6}" and "get_blockwise/4". * "append/{2,3}" and "member/3" have been moved into the "list" module and must now be invoked with the "list:" module qualifier. * "kill/3" unifies its last argument with "error(ERRNO)" on failure. * "&/2" expands into in-line task creation for local calls thus avoiding dynamic lookup. * The GHC->FLENG-translation catches redefinitions of certain internal operators. * Releasing long variable-chains tries harder to reduce stack-pressure. * Increased default heap size and goal-buffer to 5MB and 100k, respectively. * Fixed bug in "io:transfer/4". Version 9: * Added support for Mac OS X (Darwin) on Intel hardware. * Added the "foreign/1" declaration which automatically generates C wrapper code for foreign function invocations and foreign struct accessors. * Added primitives "halt/0", "statistics/1", "heap_statistics/1", "write/{1,2}" and "unify_with_occurs_check/3". * Added guard "remote/1". * "unify/3" now performs a "safe" unification: bound variables during recursive unification are undone if the full unification fails. * Moved result argument in "unify/3" to the end position for consistency with other primitives. * Added "->"/2 conditional expression operator. * Added memory consumption of floats and port objects to heap statistics log. * Expansion of extended pair arguments using "+" notation was not performed correctly in all situations. * "=:=/2" and "\=:=/2" guards did not force their arguments. * Fixed two memory leaks in the remote-variable protocol - remotely accessed variables where not reclaimed after they were resolved (Thanks to "a88" for test code that triggered these leaks.) * Fixed bug in ordering-comparison of floating-point numbers. * Fixed bug in low-level implementation of struct-field accessors that resulted in a memory leak. * Fixed stack-handling in the RISCV runtime system. * Invalid numbers in string-to-number conversion are properly shown in error messages. * Fixed bug in float-detection code used in string-to-number conversion. * Fixed an invalid float-value allocation that could cause misaligned float values on 32 bit platforms. * Decoding of UTF input streams performed overly long lookahead. * Fixed possible stack-misalignment in thread setup. * Added a workaround for implementations of "kqueue(2)" that do not detect EOF in input files (NOTE_EOF), which would result in hangs when repeatedly reading from files. * Added "module/1" declaration. * The execution statistics of synthesized predicates generated by the FGHC/Strand->FLENG translation are now merged with their parent predicates in profiling reports. * The documentation for "kill/{2,3}" had PID and signal argument swapped. * "proc" module: the exit status of a process terminated by a signal is reported as a negative exit code. * "proc" module: renamed "read/2" and "write/2" to "capture/2" and "submit/2", respectively. * "list" module: added guards to "cut/5", "take/4" and "drop/3" that are needed to make them deterministic, added "scan/5", "search/5", "trim_left/3" and "trim_right/3". * "map" module: added "lookup/4". * "io" module: added "transfer/{3,4}". * "scan" module: added "word/3". Version 8: * A git(1) repository of the sources are available now at https://gitlab.com/b2495/fleng * Fixed creation of "version.pl" when building with the sources retrieved from the git repository (reported by "matekai"). * The FGHC front-end now accepts Strand source code, which can be considered a subset of FGHC. * Added ":=/2" operator. * Block comments ("/* ... */") are now officially supported. * Strand's "machine" and "exports" declarations are accepted. * Renamed "float/1" guard and expression operator to "real/1", for concistency with Strand, renamed "float_integer_part/1" and "float_fractional_part/1" accordingly. The old names are still valid but deprecated. * Added "struct" declaration for convenient generation of tuple-field accessors. * The "occurs check" to detect circular references when unifying variables is no by default disabled due to the signifcant performance impact. It can be enabled at run-time using the "+OCCURS_CHECK' runtime option. * Renamed "string_to_float/2" to "string_to_real/2". The old name is still supported but deprecated. * Added primitives "real_to_list/2" and "list_to_real/2". * Added support for module data type: added "module/1" guard. * Added module-related primitives "get_module/2", "module_name/2", "module_exports/2" and "all_modules/1". * Added Strand's "run/2" primitive. * Added support for KL1 "extended pair" notation. * Added "chdir/1", "chmod/2", "close_file/2", 'delete_file/2", "randomize/1", "rmdir/1", "deref/1", "cancel_timer/1", "restart_timer/2", "signal/2", "kill/2" and "kill/3". * "signal/2" also accepts an integer instead of a signal name. * "randomize/2" did not fully derefence the seed argument. * "list_to_tuple" was not handling tuples of length one correctly. * Sequencing using the "&/2" operator where the first form is a primitive with an optional confirmation argument is compiled in a more efficient manner. * Sequencing a compound term like "(X, Y) & Z" now does the correct thing by executing X and Y in parallel (it was previously treated like "X & Y & Z"). * Invalid expression operators and constant computations now trigger a more meaningful error. * Removed requirement for static linkage on Linux systems that are based on musl libc (e.g. Alpine). * Fixed handling of addresses in AArch64 assembly (runtime and geenrated), which could confuse the runtime-linker on Linux. * Handle "otherwise" guard before any other guards in the same clause to ensure textually preceding clauses are fully matched. * Repaired broken handling of profiling information and combined yield/listen counters into one. * Fixed nonexistent handling of SIGPROF on Linux. * Documented "-cflags" and "-libs" options to "fleng" driver script, also added missing description of "-p" to man page. * "parse" module: renamed "parse_expression[s]" to "parse_term[s]", added "parse_term_list/{3,4}", made "vtag" argument optional (defaults to thread ticks). "parse_terms" also accepts a file descriptor as input argument, now. * "app" module: added "foreach/2'. * "list" module: added "slice/5". * "set": added "equal/3". * Added "scan" parser library module. * Fixed bug in unification of remote-port instances. * Fixed a bug in the compilation of head-matches that could cause faulty ref-counts in certain situations. * Conversion of strings and character-lists in primitives didn't check argument types thoroughly enough. Version 7: * Added a statistical profiler for FGHC/FLENG code, with new compiler option "-p" and runtime option "+PROFILE". * Fixed a bug in nested matching of structured terms where inner data calls could incorrectly succeed in the presence of suspensions. * Fixed a bug where signal-handling could cause hanging on Linux. * Fixed a ref-counting bug in local assignment of remotely exposed variables. * Added "rnd/1" computation and expression function. * The "--" after initial runtime options on the command line of compiled programs was not correctly skipped. * Functions for accessing thread-global variables have been exposed to be usable from foreign code. * Added "mode" and "provide" declarations. * Added manual page for runtime options fleng(7). * "fmt" module: dispatching for "~s" format-spec was ambiguous at could result in wrong matches. * "mem" module: most operations got an optional index argument. Version 6: * The translation of FGHC guards to FLENG has been fixed to correctly implement the semantics of clause-resumption in the presence of multiple complex guards. This both simplifies the compiler and produces more efficient code. * RISC-V (RV64IMAFD) is now supported as a target architecture (experimental). * Support for "tasks" was added, which allows (possibly nested) groups of processes to be run with a way of getting information when all processes in the group have completed execution. * Process cleanup is now done properly when the last thread terminates normally. * When cross compiling by using the "--target" configuration option, the operating system is inferred from the target triple. * When cross compiling, no compiler checks are done during configuration. * "apply/2" and "call/1" now allow direct invocations of primitive goals by synthesizing intermediate goals as necessary in most cases. * Added new primitives "merger/2", "call{2,3}", "environment/1" and "file_size/2". * Arithmetic expressions and "compute/{3,4}" have been extended to support "tan", "log", "exp", "**", "atan", "sign", "abs", "float_integer_part" and "float_fractional_part" math operators convering all functions required by ISO Prolog now. * Added the "&/2" operator to conveniently run goal sequentially using tasks. * "file_type/2" unifies the result with an error indicator on failure. * Bugfix in ordering relation for tuples with different head. * Fixed an unhandled corner case when a variable owned by another thread was locally bound while the read-request is still pending. * Fixed a bug where event-listeners on Linux could get lost when another event was triggered. * The implementation of "idle" guards has been overhauled to work properly when used with other guards and in combination with other possibly suspending clauses in the same group. * Ordering comparison for floats was broken. * Fixed some bugs in the assembler runtime for ARM. * The FGHC compiler issues warnings for some cases where goal head arguments are overlapping and no "otherwise" clause is used. * "uses" declarations are not needed anymore when a process is invoked directly for an external module. "uses" is still required when dynamic calls are used and the target is a computed goal. * "fmt" module: writing the empty list using the "~s" format specifier writes an empty string. * "io" module: "io:read_lines/2" handles lines terminated by CR+LF transparently. Added "io:read_lines_bounded/3". * "map" module: "map:keys/{2,3}" and "map:values/{2,3}" return their results in order, sorted by keys. * "app" module: added "app:take/4" and "app:drop/3". * "list" module: added "list:iota/{3, 4, 5}". * "mem" module: added some more predicates. * "proc" module: added "proc:execute/2" and "proc:shell/2". * Division by zero on x64 caused segmentation fault instead of aborting with error. * Added "-cflags" and "-libs" options to the "fleng" driver script. * Several performance improvements. * The use of native threads can be disabled at configuration time. * Added a new chapter to the manual with some useful programming tips. Version 5: * Changed licensing to public domain. * Added "-I" option to "fleng" to add include paths. * Added "thread/1" declaration to hardcode number of threads. * General tuple syntax ("{...}") is now supported. * Moved "write_char_stream/2", "write_byte_stream/2", "read_char_stream/2" and "read_byte_stream/2" into a separate library ("io"), added "read_lines/2", and "read_byte_stream_chunked/3". * "signal/3" keeps the signal handler active and delivers a stream of counts. * Dropped "get_module/2", it has no real use. * New primitives "idle_thread/1", "get_global/3", "log/2", and "restart_timer/3". * Extended "fleng-utils.h" with some functions to construct character lists and convert string-like objects to C-strings. * "app" module: added "mapreduce/4". * Debug info used for logging is now restricted to modules compiled with the "-d" option. * Inline-caches for holding module-resolutions of explicit inter-module calls are now shared, so the first call will resolve all additional calls to the same predicate appearing in the current module. * C runtime is now compiled with "-fwrapv -fno-strict-aliasing" for correctness. * Unification using "=/2" is now checked in FLENG as well as in FGHC. * Format strings in calls to one of the "fmt:format" predicates are now precompiled to give better error detection and reduce the parsing overhead at run time. * "file_exists/2" did not force the filename argument correctly. * Fixed totally broken event-processing on Linux. * "fmt" module: removed variant of "format/3" with the first arg being a file to make it less ambiguous (required for format-string precompilation). * "list" module: added "split/4" and "scan/4". * "parse" module: renamed "parse_module/4" to "parse_expressions/4", fixed a bug in "parse_expressions/4" that caused an error on end of input. * "sys" module: added an additional parameter to "attach/3", added "detach/3". * "proc" module: added "write/2" and "pipe/3", renamed "capture/3" to "read/2". * Conversion of numbers using "number_to_list/4" was broken for bases greater than 10. * Matching of complex ground literals in clause heads is now more time and memory efficient. * "cancel_timer/2" detects now when the timer already expired. * The default stack size for threads uses a fixed value (500kb) instead of using the system default. * The "plot" script did not handle multiple runs correctly, now only the last run in a log file holding data for separate runs is used for plotting data. * Stack usage is somewhat reduced when releasing large data structures that can be gbarbage collected. * If forwarded data exceeds the available space for inter-thread messages a placeholder variable is used to retrieve the rest on demand. * "Detached" message port files are cleaned up on termination. * Fixed processing of signals on Linux when a process sleeps, waiting for events. * The error for a missing process definition shows name and arity in the error message. * "halt/1" does proper termination clean up. Version 4: * Added "+LOGX" runtime option to only log explicit calls to "log/1". * The values for the runtime options "+HEAP" and "+GOALS" accept multiplier suffixes. * In FGHC "=/2" signals an error when unification fails. * Added the "list" and "app" library modules. * Added "max/2" and "min/2" expression operators for "is/2" and "compute/4". * Added support for periodic timers ("clock/3"). * Added "include/1" declaration (for both FLENG and FGHC). * The FGHC->FLENG and FLENG->ASM compilers can now be run under the "YAP" Prolog system. * The assembler code generated for x86-64 now produces AT&T syntax and can be assembled with the GNU assembler, so "nasm" is not any longer needed. * The "fleng" script allows specifying the linker to be used to produce the final executable. * Added the "apply/2" primitive as a more flexible method for producing calls at run time. * Allow a variable in goal position as a shortcut for "call/1". * Added new primitives "compare/3", "append/2", "write_byte_stream/2", "write_char_stream/2", "delete_file/2", "rmdir/2" and "chmod/2". * "fleng.h" and "fleng-utils.h" can now be used in C++ code. * Renamed "write_block" and "read_block" to "write_file" and "read_file", respectively. * Fixed several bugs in the "map" library module, added "list_to_map/{2,3}". * The "plot" utility scales the X axis to make the output more readable and also accepts the "-max" option to control the scaling. * Logging and debugging output cuts off output once it reaches a certain length. * Unification performs an occurs-check to avoid creating circular references. * Fixed padding bug when interning strings. * Each thread has its own internal string buffer for temporary strings, as it should be. * "open_file/3" now properly opens existing or creates new files. * Added "keysort/2" to the "sort" library module. * Added support for exposing a thread's message port to allow (reasonably) simple inter-process communication (see the "sys" library module for details). * Fixed a bug in the scheduler that caused excessive delays when continuously waiting for input events. Version 3: * Added support of AArch64. * Several bugfixes in Linux event-handling code. * Corrected detection of "-no-pie" to only apply to x86-64 in configuration script. * Fixed installation when used in combination with SWI Prolog. * Fixed incorrect translation of "otherwise" FGHC guards when combined with other guards. * Added primitives "string_to_byte_list/3", "cancel_timer/2", "chdir/2", "file_exists/2", "getcwd/1", "getenv/2", "file_type/2", "readlink/2", "get_global/2" and "put_global/3". * Changed "timer/2" to "timer/3', which produces an additional identfier result. * Increased message-port size to 4kb. * Added support for detached message ports (see "sys.ghc" for more information). * Fixed "length/2", which was totally broken for lists (doh). * Threads could sometimes terminate too early, even with inter-thread messages still being in flight, a more robust algorithm tries to ensure that threads never shut down while messages are still pending processing. * The empty lists is now treated as a empty (null) string, when used as argument to a primitive that requires a string or character list. * Character lists were not correctly dereferenced when containing variable references in primitives that require strings or character lists. Version 2: * Typo fix in "configure" script (reported by Mario Goulart). * Added missing "VERSION" and "fleng.mdoc" files to distribution archive (reported by "sytse"). * "-no-pie" is added when generating executables on all platforms if the C compiler supports it (reported by "sytse"). Version 1: * Initial release
gopher://schinkel.bevuta.com/1/fleng/fleng | gemini://schinkel.bevuta.com/fleng/fleng.gmi