PROL
PROL Logo
An Embeddable Java Prolog Engine
(the current version 1.01)


Introduction
    Because I think that Prolog is very powerful  computer language  It was very  interesting for me to use it in my developments but as you see it is very hardly today use anything which is not   in  mainstream of computer technologies and as I wrote on the start page, my main development language at present is Java. Because Java has now very powerfull mechanism called "annotations" it opens for us very powerfull posibilities to make own metalanguages which will help us to develop software in other ways than it  dictates by imperative languages and Prolog I'm sure is one from the best languages to be used as a meta-language. Well, I developed own Java based prolog engine to use it as a meta-language and called it as PROL (cutted version of PROLog). The engine written to process prolog programms written in the Edinburgh Prolog style but not in the Turbo Prolog style. Of course you can say me that there are a lot of implementations of Prolog engine (and for Java too) already but I developed it to understand Prolog more precisily and to learn  its  basis (and to check my some ideas in the Prolog). It has been written in Java 1.6 and can't be used with early Java versions. Because the version is permanently reviewed, I don't publish the source codes but may be I'll make it in the future. May be the main useful thing which can be used in Java, it is the possibility to attach a Java object to a Prol Term and the object moves inside a Prol engine without change  as associated with the term-owner. You should understand and remember that it is just a small amateur project.

How it works (in some words)
    As you see from the introduction, the engine based on the java annotation mechanism, it is used to define predicates and can be used to add prolog operators. The core of the prol engine work is the import com.igormaznitsa.prol.logic.ProlContext class which describes the context includes and a knowledge base. To make context you need an instance of a class which implements the com.igormaznitsa.prol.io.ProlStreamManager interface but as well you can use the default class DefaultProlStreamManagerImpl implements that interface. Then you can make consultation with an instance of  the com.igormaznitsa.prol.parser.ProlConsult class and the engine has been prepared for work. You can give goals to the engine with an instance of the com.igormaznitsa.prol.logic.Goal class and solve them with the solve() method of the class. If you want to make Java implementations of prolog predicates, you need to make own class extends  the abstract class com.igormaznitsa.prol.libraries.ProlAbstractLibrary and just to add it to a context which should use your library. I'd like to say that the JVM has not been written to work with very very deep stacks and I have very strange cases in the deep stack work (as well it is needed to use -Xss to increase the stack depth in Java), under Linux (Ubuntu) the JVM works with more deep stack than under Windows XP. The tail recursion is not implemented in the engine. The predicate list of the  prol core libraries (which are placed in the engine jar) can be read through the link.

The embedded GUI micro-editor
    The library has embedded small GUI editor allows to edit and start Prol scripts. The editor has four windows and you can make dialog between the user and the script with it. May be it would be useful for beginners to research the Prolog and write small test applications.
Prol pad GUI

A Few examples
   It is very easy to describe a predicate. As an example I show you how is implemented the SORT/2 predicate in the core library. As you can see you just need place @Predicate annotation before a function (which has a Goal and TermStruct as arguments).
    @Predicate(Signature = "sort/2", Template = {"+list,?list"},Reference="True if Sorted can be unified with a list holding the elements  of List, sorted to the standard order of terms")
    @Determined
    public static final boolean predicateSORT(final Goal goal, final TermStruct predicate) {
        final Term nonsorted = Utils.getTermFromElement(predicate.getElement(0));
        final Term sorted = Utils.getTermFromElement(predicate.getElement(1));
        final Term[] bufferarray = Utils.listToArray((TermList) nonsorted);
        Arrays.sort(bufferarray, Utils.TERM_COMPARATOR);
        final TermList sortedList = Utils.arrayToList(bufferarray);
        return sorted.Equ(sortedList);
    }

If you want to define some operators in your library, you need use a ProlOperators annotation placed before the library class declaration and fill the annotation array with Operator annotations for every operator.
@ProlOperators(Operators = {
    @ProlOperator(Priority = 700, Type = Operator.OPTYPE_XFX, Name = "is"),
    @ProlOperator(Priority = 700, Type = Operator.OPTYPE_XFX, Name = "="),
    @ProlOperator(Priority = 1000, Type = Operator.OPTYPE_XFY, Name = ","),
    @ProlOperator(Priority = 1050, Type = Operator.OPTYPE_XFY, Name = "->"),
....
    @ProlOperator(Priority = 300, Type = Operator.OPTYPE_XFX, Name = "mod"),
    @ProlOperator(Priority = 200, Type = Operator.OPTYPE_FY, Name = "\\"),
    @ProlOperator(Priority = 200, Type = Operator.OPTYPE_XFX, Name = "**")
})
public class ProlCoreLibrary extends ProlAbstractLibrary {
...


   Below you can see the source shows possibilities of the engine use in a Java program and show you the example which solves the Eight Queen task. The source below describes the task and will find all solutions for the Eight Queen chess task and print them.
           final ProlContext context = new ProlContext("test",DefaultProlStreamManagerImpl.getInstance());
           final ProlConsult consult = new ProlConsult("solution([]). solution([X/Y|Others]):-solution(Others),member(Y,[1,2,3,4,5,6,7,8]),notattack(X/Y,Others). notattack(_,[]). notattack(X/Y,[X1/Y1 | Others]):- Y=\\=Y1, Y1-Y=\\=X1-X, Y1-Y=\\=X-X1, notattack(X/Y,Others). member(Item,[Item|Rest]). member(Item,[First|Rest]):-member(Item,Rest). template([1/Y1,2/Y2,3/Y3,4/Y4,5/Y5,6/Y6,7/Y7,8/Y8]).", context);
            consult.consult();

            final Goal goal = new Goal("template(X),solution(X).", context);
            int combinatioCounter = 0;

            while (true) {
                final Term result = goal.solve();
                if (result == null) {
                    break;
                }
                Utils.printTermState(result);
            }

Download

    You can download the archive contains the JavaDoc for the engine, examples and the compiled JAR of the library. The library can be used and distributed in any kind of projects (free, commercial and other) without any restrictions. You can download the archive through the direct link.

Change history
1.01
  • Bugfixing
  • The core prol library was exapnded with new predicates
  • String and graphic prol libraries were added
  • A small notepad to edit and execute prol scripts was embedded into the jar
1.00a
  • The first published version of the engine


Conclusion
    I can't say that the engine is "a new word" or it works very quickly and optimally but it is one more way to use the Prolog language from Java that can be very useful for different applications. The engine allows really make  easier the use of both Java and Prolog.in the bounds of the same application.
 

© 2003-2010 Igor A. Maznitsa. All Rights reserved.