Erlog is a Prolog interpreter implemented in Erlang and integrated with the Erlang runtime system. It is a subset of the Prolog standard. An erlog shell is also included.
Make erlog:
make rel
To use local shell just run erlang emulator in directory with compiled beam files (ebin
) and run local shell:
make
cd ebin
erl
erlog_local_shell:start().
You can use remote shell and connect to it via telnet. Run release:
./rel/erlog/bin/erlog start
And connect to it via console:
telnet 127.0.0.1 8080
Port can be set up in src/erlog.app.src
.
Debugger can be passed to erlog as a parameter {debugger, Fun}, where Fun
is your fun of calling debugger:
{ok, Core} = erlog:start_link([{debugger, fun(Status, Functor, Result) -> gen_server:call(Debugger, {Status, Functor, Result}) end}]),
Where Status is a status of command - ok|failed
, Functor is current working functor, Result is a result
prolog term - complex structure with all data.
As an example you can use erlog_simple_debugger
with erlog_local_shell
:
{ok, Pid} = erlog_simple_debugger:start_link().
erlog_local_shell:start(Pid).
More in docs.
Spawn new logic core:
{ok, Pid} = erlog:start_link().
Process prolog terms, using your core:
erlog:execute(Worker, Command).
Where:
Command
is a command, ended with dot,
Worker
is a pid of your prolog logic core.
When erlog:execute returns select
in result - you can select for some other result calling erlog:select/2
instead of execute.
erlog:select(Worker, ";").
Full Example:
(erlog@127.0.0.1)1> {ok, Pid} = erlog:start_link().
{ok,<0.961.0>}
(erlog@127.0.0.1)2> erlog:execute(Pid, "assert(father('victor', 'andrey')).").
true
(erlog@127.0.0.1)3> erlog:execute(Pid, "father('victor', 'andrey').").
true
(erlog@127.0.0.1)4> erlog:execute(Pid, "father('victor', 'vasya').").
false
(erlog@127.0.0.1)5> erlog:execute(Pid, "run(S).").
{{true,[{'S',600}]}, select}
(erlog@127.0.0.1)6> erlog:select(Pid, ";").
false
Erlog now supports using your own database, instead of using ets and dicts. Just implement erlog_storage
callback interface
and pass your module name with your implementation to erlog:start_link/1
as database to configuration list.
Example:
ConfList = [{database, mysql_storage_impl_module}],
erlog:start_link(ConfList).
You can pass your parameters to your database implementation:
ConfList = [{database, dbModule}, {arguments, Params}],
erlog:start_link(ConfList).
Where Params
is a list of your args, need to be passed to dbModule:new/1
function.
To consult files use brakes and filename with path ["/home/prolog_user/prolog_code/examples/family.pl"]
.
Erlog also supports calling consult/1
and reconsult/1
from prolog code:
erlog:execute(Pid, "consult(\"/home/prolog_user/prolog_code/examples/family.pl\").").
Remember! For proper consulting files with default consulter, files should end with empty line!
File consulter is a module, used to operate with files. It's behaviour is described in erlog_file_consulter
. It should
implement two functions: lookup
and load
. Lookup returns list of all prolog libraries from selected directory and load
reads selected file and parse it to prolog terms.
Default implementation use files and directories for libraries search and loading. If you implement your own file consulter,
f.e. if you use database filesystem or smth else - implement erlog_file_consulter
behaviour in your module and pass its
name in erlog configuration as f_consulter:
ConfList = [{f_consulter, my_hadoop_consulter}],
erlog:start_link(ConfList).
If you wan't to use functions from debug library - you should define your own gen_event handler and pass it to erlog.
All debug events from such debug functions as writeln/1
will be passed there.
See erlog_simple_printer
as a default implementation of console printer as an example, or erlog_remote_eh
, which is
intended to print debug to remote client.
To configure your gen_event module - just pass module and arguments as event_h in configuration:
ConfList = [{event_h, {my_event_handler, Args}}],
erlog:start_link(ConfList).
Erlog supports two kinds of libraries: native (written in Erlang) and extended (written in Prolog). Native libraries can
be standard and external.
All predicates from standard libraries are loaded to memory when you start erlog core.
All prolog libraries from lib/autoload
are also loaded to memory when you start erlog core.
But to use predicates from external functions - you should manually load them to memory with the help of use/1
command:
| ?- db_assert(test,foo(a,b)).
false
| ?- use(erlog_db).
true
| ?- db_assert(test,foo(a,b)).
true
This example demonstrates the loading of external database library.
First call is false, because there is no such function loaded to memory.
Second - library is loaded.
Third - function run successfully.
Important! If you are working with erlog from poolboy or dynamic creating erlog gen_servers through supervisor,
remember, that two execution requests can be processed on different erlog instance.
use(some_lib). %returns true
some_lib_fun(some_val). %returns false
In this example system erlog gen server is created one per one separate command (F.e. http request). Firstly - library
some_lib
is loaded. Than erlog server with loaded library is destroyed (as request is complete) and for another request
some_lib_fun(some_val)
another erlog server is created, but, without loaded library.
For convenient libraries usage you can load all libraries you need when creating a core. It will let you not to call use/1
everywhere in your code. Just add param {libraries, [my_first_lib, my second_lib]}
in your params when starting a core:
ConfList = [{libraries, [Lib1, Lib2]}],
erlog:start_link(ConfList).
All libraries from array will be loaded. More in docs.
When configuring erlog you should set default library directory as libs_dir:
ConfList = [{libs_dir, "/usr/share/prolog/lib/"}],
erlog:start_link(ConfList).
If you don't set this - erlog will use ../lib
directory, assuming it was run from ebin
.
For manual loading prolog library - also try use
, but instead of atom name call it with string library name:
use(erlog_cache). %use extended native library
use("proc/cuda/driver.pl"). %use prolog library, from /usr/share/prolog/lib/proc/cuda/
Important! To avoid erlog_parse,{operator_expected,'.'}
error - sure, that last character in your prolog file is \n
.