DRAFT -- ECLiPSe 7.0 Release Notes
The main news for this release is the introduction of the multi-engine/multi-thread functionality.
Engines and Threads
An 'engine' is an entity with independent control flow and data areas. In previous versions of ECLiPSe, all code executed in a single, implicit engine. Starting with release 7, engines can be freely created and manipulated.
The essential characteristics of engines are:
- backtracking in one engine does not affect another
- engines can operate in a concurrent or interleaved fashion
- communication between engines is explicit
This opens up a range of new programming techniques, such as
- multithreaded servers
- parallel algorithms
- multiple independent search trees
- engine_create(-Engine, ++Options)
- Create a new ECLiPSe engine
- engine_resume(+Engine, +Term, -Status)
- Resume execution of an engine and return result status
- engine_resume_thread(+Engine, +Term)
- Asynchronously resume execution of an engine (in a separate thread)
- engine_join(+Engine, +Timeout, -Status)
- Wait for an engine to stop running, and return its status
As an alternative interface to the multithreading functionality, we provide library(threads), which implements the functionality defined in ISO/IEC DTR 13211-5:2007.
New Built-In Predicates
Further engine-related functionality
- engine_post_event(+Engine, +Event)
- Post an event to an engine
- engine_properties(+Engine, -Properties)
- Obtain a list of the engine's properties
- Get a handle of the engine executing the call
- engine_status(+Engine, -Status)
- Obtain the status of an engine
- yield(+ToParent, -FromParent)
- Stop the running engine in the yielded-state, and wait for resume
New string operations have been added in coordination with SWI-Prolog.
- read_string(+Stream, +SepChars, +PadChars, -Separator, -String)
- string_char(?Index, +String, ?Char)
- string_chars(?String, ?Chars)
- string_code(?Index, +String, ?Code)
- string_codes(?String, ?Codes)
- string_concat(?String1, ?String2, ?String3)
- string_lower(++String, -Upper)
- string_upper(++String, -Upper)
- sub_string(+String, ?Before, ?Length, ?After, ?SubString)
- text_to_string(++Text, -String)
- term_string(?Term, ?String, +Options)
New storage primitives have been introduced, mainly for convenience in multithreaded applications.
- shelf_get_and_dec(+ShelfHandle, +Index, -OldValue)
- shelf_inc_and_get(+ShelfHandle, +Index, -NewValue)
- shelf_test_and_set(+ShelfHandle, +Index, +Expected, ?NewValue)
- store_insert(+StoreHandle, ++Key, ?Value)
- store_remove(+StoreHandle, ++Key, -Value)
- store_update(+StoreHandle, ++Key, -OldValue, ?NewValue)
- store_test_and_set(+StoreHandle, ++Key, ++OldValue, ?NewValue)
Names and handles
- Replaces getval/2 for named references
- Replaces setval/2 for named references
- Test for a handle of a particular class, or query a handle's class
- Get an anonymous handle from a name
Mutual exclusion and thread synchronisation
- with_mutex(++Handle, +Goal)
- Equivalent to once(Goal) but with mutual exclusion
- condition_signal(+Handle, +Mode)
- Signal a condition on a handle
- condition_wait(+Handle, +Timeout)
- Wait for a condition to be signaled on a handle
- like recordz/2, but with synchronization
- like erase/2, but with synchronization
Term testing and manipulation
- term_variables(?Term, -Vars) - semantic change!
- See below.
- term_variables_array(?Term, -VarArray)
- Like term_variables/2, but returning an array.
- term_variables_count(?Term, -VarCount)
- Count of distinct variables.
- A library providing higher-level primitives for concurrent/multi-thread programming, implemented using engines.
- A library implementing sequential best-first-search in conjunction with propagation-based solvers. It works by recomputing search states.
- A library handling operations on lists of structures, in particular where one structure element serves as a key.
New Compatibility Libraries
- A small library containing predicates whose semantics changed in this release, in particular term_variables/2.
- A compatibility wrapper for library(ic) to simplify running of code developed for SICStus Prolog's library(clpfd) and SWI-Prolog's library(clpfd).
- Implements Bart Demoen's attributed variable API (as used by hProlog and SWI-Prolog). These are implemented on top of ECLiPSe's native attributed variable functionality, and can be mixed with those.
- A utility library to help type checking and raising ISO-Prolog compatible exceptions.
- A compatibility wrapper that implements a thread-interface as defined in ISO/IEC DTR 13211-5:2007 on top of ECLiPSe's multi-engine functionality.
- A library simplifying the use of higher-order terms.
- Allowed 3rd argument for goal-return to pre_unify handler for attributes. Full implementation of verify_attributes/3 in lib(atts), runs SICStus manual examples without change.
- bb_min/3 has a new option for finding all optimal solutions (solutions:one/all)
- added easter_mjd/2
- added hash_list/2, hash_insert/3
- library(iso_strict) and library(iso)
- conformance to ISO-Prolog corrigendum 3, and elimination of remaining discrepancies in output spacing
- added maplist/2, collection_to_array/2
- improved compatibility
- Global flags (get_flag/2)
- A new flag cpu_count indicates the number of logical processors on the machine, which can be helpful in deciding how many threads to create. The new flags default_localsize and default_globalsize determine the default stack sizes for additional engines. The enable_interrupts flag has been removed (interupts are now handled by a separate thread).
- Statistics statistics/2 and cputime/1
- New statistics items: cputime (like cputime/1, gives thread cpu time), dict_gc_countdown (remaining functor creations until dictionary garbage collection gets triggered), dict_gc_running (true if a dictionary GC is currently underway).
- Generalized sort/4 and merge/5
- The sort/4 and merge/5 predicates accept additional order specifications, making number_sort/4 and number_merge/5 obsolete (coordinated with SWI).
- Updated printf/2,3
- Better formatting options for strings, removed restrictions regarding bignums.
- New DCG implementation
- The Definite Clause Grammar translator (for clauses of the form H-->B) has been revised, maximising compatibility and fixing some long-standing bugs.
- Interrupt/Signal handling
- Non-fatal signals are now handled by a dedicated thread, and because of multi-threading, there is no longer a notion of "the interrupted execution". As a result, an interrupt handler can no longer abort a running execution by calling throw/1, but has to be designed to deal appropriately with all the running application threads.
- Term variables
- The term_variables/2 built-in predicate historically returned a variable list in reverse order of left-to-right occurrence in Term. This was unusual, made the predicate non-idempotent, and didn't agree with the ISO Prolog standard. The order has now changed to correspond to the order in which the variables occur in Term in a depth-first, left-to-right traversal. Unfortunately, the change may have subtle effects on programs developed on previous ECLiPSe versions, such as different search trees in constaint programs. The old version can be imported from library(eclipse_6) if necessary.
- Syntax - back-quote character
For eclipse_language, we have changed the default character class of the
`(code point 96) from
list_quote. This allows lists of character codes to be written like `abc` (compatible with SWI-Prolog). Applications that use this character for constructing unquoted symbolic atoms (like
`=) will have to use a
(0'`,symbol)declaration to locally restore the original behaviour.
- Syntax - radix notation
- The syntax option based_bignums is now enabled by default. This means that integers written in radix notation can be larger than the machine's word size, and are not interpreted as two's complements. E.g. 16'ffffffffffffffff is read as 18446744073709551615 rather than -1.
- Term writing - spacing
- In compact-mode (write-option compact(true), or per-module syntax_option(dense_output)), the term writing built-ins now suppress redundant blank space more aggressively than previously. In non-compact mode, spaces are always printed between operators and their arguments.
- Term writing - parentheses
- When printing terms with prefix functor -/1 and +/1, redundant parentheses are no longer printed. Instead, space is inserted if necessary. (This applies only to modules using traditional ECLiPSe syntax; for modules using ISO syntax, the rules required by standard corrigendum 3 apply).
Performance should generally not be very different from release 6.1. However, there were a number of implementation changes related to the multithread capability, for example related to locking access to shared data structures. If you notice any unexpected effects, please contact firstname.lastname@example.org. Other points are:
- Some speed improvements to simple arithmetic.
- The change of the order of the result list in term_variables/2 could have large effects (either way) on performance, if it is used in the computation of the variable list for labeling in constrained search applications. If in doubt, use the compatibility version available in library(eclipse_6).
This release is available for the following architectures:
- NEW: Linux/ARM 32-bit (armv7_linux), for Raspberry Pi 2&3
- Linux/x86 (Intel, AMD,...) 32-bit (i386_linux)
- Linux/x86-64 (Intel, AMD) 64-bit (x86_64_linux)
- Mac OS X/Intel 64-bit (x86_64_macosx)
- Windows 32-bit (i386_nt)
- Windows 64-bit (x86_64_nt)