Operands and equation questions

It’s known that Prolog have a powerful feature that new operands can be defined.
Assume that my program defined a set of new boolean operands such as bool1, bool2, bool3, my_and.

:-op(500, yfx, [bool1, bool2, bool3]).

:-op(700, xfx, [my_and]). (my_and == logic and)

now, for this equation for example: a bool1 b my_and c bool2 d Prolog will translate it into my_and(bool1(a, b), bool2(c, d)).
Also, if I will look at this as a binary tree it supposed to look like this:

                              my_and
                           /         \
                      bool1            bool2
                     /     \          /     \
                    a       b       c        d
  1. Is there any way to print the equation as a binary tree?
  2. Is there any way to split the equation into sub equations?
  3. Assume that my program gets new fact every minute. it is possible to check only the right part of the equation and not all of it?
    Explain:
    For the equation: a bool1 b my_and c bool2 d
    at time 0 the program get a - the equation will return false since a bool1 b not happened.
    at time 1 the program get b (and a bool1 b is true) - the equation still return false since the right side is still false.
    at time 2 the program get c - the equation will return false (same reason as time 1).
    at time 3 the program get d (and c bool2 d is true) - the equation return true since the left and the right are true.
    In each new time that new fact was inserted the program check the for whole equation, even the left side already was true since time 1.

Thank you for your time and help.

Try gvterm for formatted display, after installed with

?- pack_install(gvterm).
example
/*  File:    x_gvterm.pl
    Author:  Carlo,,,
    Created: Oct  5 2020
    Purpose: https://swi-prolog.discourse.group/t/operands-and-equation-questions/3007
*/

:- module(x_gvterm,
          [test/0]).

:- use_module(library(gvterm)).

:-op(500, yfx, [bool1, bool2, bool3]).
:-op(700, xfx, [my_and]). % my_and == logic and

eq(a bool1 b my_and c bool2 d).

test :-
    eq(E),
    dotty_term(E).
2 Likes

I got this warning and nothing happen :confused:

Warning: [Thread 3] Thread running “run_dotty(xdot,‘c:/Users/westly/AppData/Local/Temp/2’)” died on exception: source_sink path(xdot)’ does not exist

The pack gvterm, IIRC will generate a dot file. A dot file is an input specification for GraphViz.

I take that you have never used GraphViz? If not you will need to install GraphViz and then run the GraphViz dot command to convert the dot file into an output format such as SVG, PNG, PDF, etc.

There is some example code of doing this in Convert facts to GraphViz dot file using DCGs, specifically

SET PATH="C:\Program Files (x86)\Graphviz2.38\bin"
dot -Tsvg module_graph.dot -o module_graph.svg

HTH

1 Like

Great, It works for me now :slight_smile:
Any idea what about my third question? It is possible?

Assume that my program gets new fact every minute. it is possible to check only the right part of the equation and not all of it?
Explain:
For the equation: a bool1 b my_and c bool2 d
at time 0 the program get a - the equation will return false since a bool1 b not happened.
at time 1 the program get b (and a bool1 b is true) - the equation still return false since the right side is still false.
at time 2 the program get c - the equation will return false (same reason as time 1).
at time 3 the program get d (and c bool2 d is true) - the equation return true since the left and the right are true.
In each new time that new fact was inserted the program check the for whole equation, even the left side already was true since time 1.

My first thought is that it might be possible, and if it were my problem I would take the time to try to develop it into working code. However the only thing this reminds me of is how parsers have changed over the years from being a batch process and parsing an entire file to real time parsing of lines within an IDE to give back more specific errors.

This also reminds me of BDD (Binary decision diagram), I am thinking that the Reduced Ordered Binary Decision Diagram could be used to short cut the process, but don’t ask me how, it is just a WAG.


On a side note. I am actually working through the entire creation of the image based on your question and realized that gvterm wants to use xdot. I am guessing that you installed GraphViz, set up the path to xdot and then the process worked to display the graph? If so, then you should note that in your response.

Since your question is of value to others learning Prolog at a beginner or intermediate level I am creating a Nice to Know topic to give an example of this based on your question. :slightly_smiling_face:


See: Using SWI-Prolog pack gvterm

Thank you.
About my third question, I hope it can be done…
About the side note, gvterm wants to use xdot as you said and return the same warning.
Only a the manual steps works for me.

SET PATH=“C:\Program Files (x86)\Graphviz2.38\bin”
dot -Tsvg module_graph.dot -o module_graph.svg

In looking at the gvterm code in the local installation (C:\Users\Groot\AppData\Local\swi-prolog\pack) found a directory named script that has a file named xdot containing a Python program; did not know this. However I still think the more practical way to do this is to convert it to a static format such as SVG,PNG,PDF, or a dynamic output via Cytoscape.js.


readme.md from gvterm

---+ Render Prolog terms using graphviz (dot).

---++ Additional installation

   - copy script/xdot to a place in $PATH
   - Ensure python is installed to run the xdot script
   - Ensure graphviz (http://www.graphviz.org/) is installed in $PATH

If one changes the test code to

test :-
    eq(E),
    % dotty_term(E).
    term_to_dot(E).

then

?- test.
digraph structs {
  node [shape=record];
  struct4 [label="<f> my_and |<a0> .|<a1> ."];
  struct5 [label="<f> bool1 |<a0> a|<a1> b"];
  struct6 [label="<f> bool2 |<a0> c|<a1> d"];

  struct4:a0 -> struct5:f;
  struct4:a1 -> struct6:f;
}
true.

will output the dot specification to the console. This can easily be put into a file and passed to the GraphViz dot command.

Running the following will generate the file test.dot with the GraphViz dot specification

?- tell('./test.dot'),test,told.
true.

SWISH can also display terms as a tree in a graphical representation. See: The term render plugin. Noted by Jan W. in this post.