Stream reasoning / Reactive programming in prolog?

2019-03-28 17:05发布

问题:

I was wondering if you know of any way to use prolog for stream processing, that is, some kind of reactive programming, or at least to let a query run on a knowledge base that is continuously updated (effectively a stream), and continuously output the output of the reasoning?

Anything implemented in the popular "prologs", such as SWI-prolog?

回答1:

You can use Logtalk's support for event-driven programming to define monitors that watch for knowledge base update events and react accordingly. You can run Logtalk using most Prolog systems as the backed compiler, including SWI-Prolog.

The event-driven features are described e.g. in the user manual: http://logtalk.org/manuals/userman/events.html

The current distribution contains some examples of using events and monitors. An interesting one considering your question is the bricks example: https://github.com/LogtalkDotOrg/logtalk3/tree/master/examples/bricks

Running this example first and then looking at its code should give you as good idea of what you can do with system wide events and monitors.



回答2:

XSB has stream processing capabilities. See page 14 in the

XSB Manual



回答3:

I'm working on something related, in project pqConsole already there is the basic capability: report to the user structured data, containing actionable areas (links) that call back in Prolog current state, hence the possibility to expose actions and react appropriately (hopefully).

It's strictly related to pqConsole::win_write_html, showcasing recent Qt capabilities of SWI-Prolog.

Here an example of a snippet producing only a simple formatted report, I'll try now to add the reactive part, so you can evaluate if you find expressive this basic system. Hints are welcome...

/*  File:    win_html_write_test.pl
    Author:  Carlo,,,
    Created: Aug 27 2013
    Purpose: example usage win_html_write/1
*/

:- module(win_html_write_test,
      [dir2list/1
      ]).

:- [library(http/html_write)].
:- [library(dirtree)].

dir2list(Path) :-
    dirtree(Path, DirTree),
    % sortree(compare_by_attr(name), DirTree, Sorted), !,
    DirTree = Sorted,
    phrase(html([\css,
             \logo,
             hr([]),
             ul(\dirtree2html(Sorted, [])),
             br([])]), Tokens),
    with_output_to(atom(X), print_html(Tokens)),
    win_html_write(X),
    dump_page_to_debug(X).

css --> html(style(type='text/css',
           ['.size{color:blue;}'
           ])).

logo --> html(img([src=':/swipl.png'],[])).

dirtree2html(element(dir, A, S), Parents) -->
    html(li([\elem2html(A),
         ul(\elements2html(S, [A|Parents]))])).
dirtree2html(element(file, A, []), _Parents) -->
    html(li(\elem2html(A))).

elem2html(A) -->
    {memberchk(name=N, A),
     memberchk(size=S, A)
    },
    html([span([class=name], N), ' : ', span([class=size], S)]).

elements2html([E|Es], Parents) -->
    dirtree2html(E, Parents),
    elements2html(Es, Parents).
elements2html([], _Parents) --> [].

dump_page_to_debug(X) :-
    open('page_to_debug.html', write, S),
    format(S, '<html>~n~s~n</html>~n', [X]),
    close(S).

This snippet depends on dirtree, that should be installed with

?- pack_install(dirtree).

edit With 3 modifications now the report has the ability to invoke editing of files:

  • call to get paths in structure
    dir2list(Path) :-
        dirtree(Path, DirTreeT),
        assign_path(DirTreeT, DirTree),
        ...
  • request a specialized output for files only
    dirtree2html(element(file, A, []), _Parents) -->
        html(li(\file2html(A))).
  • finally, the 'handler' - here just place a request to invoke the editor
    file2html(A) -->
        {memberchk(name=N, A),
         memberchk(path=P, A),
         memberchk(size=S, A)
        },
        html([span([class=name],
                   [a([href='writeln(editing(\'~s\')), edit(\'~s\')'-[N,P]], N)]
        ), ' : ', span([class=size], S)]).

and now the file names are clickable, write a message and get edited if requested: a picture