Making it stick.

"I have a mind like a steel... uh... thingy." Patrick Logan's weblog.

Search This Blog

Loading...

Wednesday, December 07, 2011

Calling Prolog from Java with Prolog Cafe

A couple two, three more details from yesterday's post. The first is how to establish the package name for a Prolog source file being compiled to Java:

Simply put the following at the top of the Prolog source:


:- package 'com.example.foo'.

Now, calling predicates from Java: each predicate and arity is compiled from Prolog to its own Java class. For example the following Prolog source:


main :-
 queens(8, Qs), write(Qs), nl, fail.

queens(N,Qs) :-
 range(1,N,Ns),
 queens(Ns,[],Qs).

queens([],Qs,Qs).
queens(UnplacedQs,SafeQs,Qs) :-
 select(UnplacedQs,UnplacedQs1,Q),
 not_attack(SafeQs,Q),
 queens(UnplacedQs1,[Q|SafeQs],Qs).

%% ...and so on.

If you omit the package name then the package defaults to "user" and the compiler creates a "user" directory for the Java source. Otherwise the Java files will be placed in a nested source tree corresponding to the package name you've defined.

The section of code above defines three predicates:

  • main/0 is compiled to a class named PRED_main_0 (i.e. a class for a predicate with no arguments, "arity zero")
  • queens/2 is compiled to a class named PRED_queens_2 (i.e. a class for the two-argument predicate, "arity two")
  • queens/3 is compiled to a class named PRED_queens_3 (i.e. a class for the three-argument predicate, "arity three")

These predicates can be called from Java using the Prolog Cafe API. The predicate main/0 will display the results to standard output using the write/1 and nl/0 predicates which write a given term and write a newline, respectively. Running that predicate was illustrated in yesterday's post.

If you want to find the values of the logic variables given in a goal, then the Java would look something like:


IntegerTerm eight = new IntegerTerm(8);
VariableTerm solution = new VariableTerm();
PRED_queens_2 queens = new PRED_queens_2(eight, solution, Failure.FAILURE);
BlockingPrologControl prolog = new BlockingPrologControl();
prolog.setPredicate(queens);
StringBuffer buf = new StringBuffer();
for (boolean r = prolog.call(); r; r = prolog.redo()) {
    buf.append("A solution: " + solution + "\n");
}
queens_solutions = buf.toString();

This Java code creates an instance of the queens/2 predicate corresponding to the following Prolog: queens(8, Qs), fail.

Constructors for a predicate instance require a "continuation" argument. Lacking no other interesting continuation, the default choice is Failure.FAILURE, a built-in predicate telling the search to backtrack for further solutions.

The IntegerTerm eight is a constant, telling the application to try to place eight queens. And the VariableTerm is a logic variable telling the application to unify found solutions with this variable.

BlockingPrologControl is going to conduct the search to satisfy its given predicate. The call method tries to find a solution, and returns true if it does. Subsequent calls to redo try to find further solutions, finally returning false when no more solutions exist.

The loop iterates once per solution. With each iteration the value of the logic variable, solution, is unified with the current solution. This code simply builds a string of all of the solutions, and I happened to use just one logic variable in the goal.

If you're not (yet) a Prolog programmer, note that a clause can have any number of variables, and the search will attempt to satisfy each of them so that the whole solution is true. Given the following definition of append/3, in which the third term is logically equated to the first term appended to the second term:


append([X|Y],Z,[X|W]) :- append(Y,Z,W).
append([],X,X).

The following goal will attempt to find values for each of the variables such that the two appends are satisfied:


append([N], [Y, Z], [X, 2, 3]), append([3], [2, 1], [3, 2, N]).

There is one solution:


N = 1,
Y = 2,
Z = 3,
X = 1

See that the variables N and X are unified to each other, and unified to the number 1 as well.

Tuesday, December 06, 2011

Prolog in Java

There are a number of implementations of Prolog in Java. Most of them are interpreters, and a number of those implement a complete Prolog system. Most implementations are a bit dated.

Wanting to get a bit more speed but remain in the JVM, I took a look at Prolog Cafe, which compiles Prolog to Java source. Even better, the source is as recent as 2009.

Then I looked around to see who might be using Prolog Cafe, and how recently. Even better news: The Gerrit code review system uses Prolog Cafe for rule checking. The team has been actively supporting a fork off the last original release of 1.2.5.

I just began trying Prolog Cafe (the new fork) this morning. The most significant difference so far is the Java package namespace. Below are a few notes illustrating the system, based off the original documentation, using the new namespace, etc.

  1. Install SWI Prolog for bootstrapping.
  2. cd to the prolog-cafe source directory.
  3. make

The package namespace has changed from
jp.ac.kobe_u.cs.prolog.*
to: com.googlecode.prolog_cafe.*.

Prolog Cafe has an interpreter. Try it:


java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria
Prolog Cafe 1.2.5 (mantis)
Copyright(C) 1997-2009 M.Banbara and N.Tamura
| ?- [queens].
{consulting /home/patrick/dev/prolog-cafe-ex/queens.pl ...}
{/home/patrick/dev/prolog-cafe-ex/queens.pl consulted 350 msec}
| ?- main.
[4,2,7,3,6,8,5,1]
[5,2,4,7,3,8,6,1]
[3,5,2,8,6,4,7,1]
[3,6,4,2,8,5,7,1]
...

Compile Prolog to Java:


java -cp $PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.compiler.Compiler ../queens.pl

Compile the resulting Java:


javac -d . -cp $PLCAFEDIR/plcafe.jar user/*.java

Run the compiled code:


java -cp .:$PLCAFEDIR/plcafe.jar com.googlecode.prolog_cafe.lang.PrologMain com.googlecode.prolog_cafe.builtin:cafeteria

Prolog Cafe 1.2.5 (mantis)
Copyright(C) 1997-2009 M.Banbara and N.Tamura
| ?- main.
[4,2,7,3,6,8,5,1]
[5,2,4,7,3,8,6,1]
[3,5,2,8,6,4,7,1]
[3,6,4,2,8,5,7,1]
[5,7,1,3,8,6,4,2]
[4,6,8,3,1,7,5,2]
[3,6,8,1,4,7,5,2]
[5,3,8,4,7,1,6,2]
[5,7,4,1,3,8,6,2]
[4,1,5,8,6,3,7,2]
...

Saturday, August 27, 2011

The Relative Coordinate Systems of Cappuccino's CPView

Cappuccino's Objective-J API is based on the Objective-C source for NeXTStep. NextStep was developed at NeXT in the 1980's. At that time it was considered the premier GUI programming API. As it happens the corresponding Cappuccino API should be considered the premier browser-based, "rich", "single-page app", whathaveyou, programming API.

I added a simple example to github which illustrates how easy it is to create multiple subdivided views that resize appropriately as the browser window resizes. Or you could use HTML5/CSS3 and write "puns" to trick the web page layout model into behaving like a window system. I find the straightforward approach significantly more productive.

The best way to solve a complex programming problem is to address simpler problems that add up. The nested views with relative coordinate systems goes back to something like the beginning of computer graphics. Complex layouts become simple combinations of much simpler layouts.

I'm putting most of my exposition in the README.org and jotting about updates on subjot, e.g. this one, or watch the github repository itself.

Tuesday, August 23, 2011

Objective-J Exuberant Ctags Regex

The following does a decent job of indexing Objective-J source using Exuberant Ctags (a ctags/etags replacement with a lot of features). Based on Greg Sexton's regexps for Objective-C.

--langdef=objj
--langmap=objj:.j
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+):[[:space:]]*\(/\1/m,method/
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+)[[:space:]]*\{/\1/m,method/
--regex-objj=/^[[:space:]]*[-+][[:space:]]*\([[:alpha:]]+[[:space:]]*\*?\)[[:space:]]*([[:alnum:]]+)[[:space:]]*\;/\1/m,method/
--regex-objj=/^[[:space:]]*\@implementation[[:space:]]+(.*)$/\1/c,class/

Sunday, August 21, 2011

Double Dispatch In Objective-J

My previous post describes a controller for separating an application's model from Cappuccino's CPOutlineView. But there's actually one place where the model and view kind of meet up:

- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
  return (nil == item) ? @"" : [item objectValueForOutlineColumn: tableColumn];
}

I decided to have the controller give a model class access to a column, which is part of the view. Why?

This example has four kinds of columns and three kinds of model classes. Each column wants to display each kind of model element differently. One obvious solution is to use a conditional expression:

if the column is a ... and the model element is a ... then ...

But even simple object-oriented languages like Objective-J have easy mechanisms and patterns for reducing the need to test objects for their class or whether they implement some specific message. Going way back in Smalltalk lore, there's Double Dispatch.

The goal is to reveal to a column the presentation object to use in each of its rows. To do so, the column view, CPTableColumn, is subclassed for each kind of column in the example's outline:

  • SDNavigationColumn
  • SDTopicColumn
  • SDNotesColumn
  • SDDateColumn

Each of these subclasses implements the following methods:

  • objectValueForTopLevel:
  • objectValueForPriority:
  • objectValueForStuff:

Each of the model classes implements objectValueForOutlineColumn: by sending one of the above messages to the given column. For example, SDStuff is implemented as follows:

- (id)objectValueForOutlineColumn:(id)anOutlineColumn
{
  return [anOutlineColumn objectValueForStuff: self]; 
}

This dispatches right back ("double dispatch") to have the column respond with the awareness that it is on a row for detailed stuff. Each column will be interested in different aspects of the stuff. The navigation column is only interested in hierarchy and not details. Here is its implementation, which just returns the empty string to indicate its disinterest:

- (id)objectValueForStuff:(SDStuff)aStuff
{
  return "";
}

On the other hand the date column is interested in a presentation of the given date:

- (id)objectValueForStuff:(SDStuff)aStuff
{
  return [[[aStuff date] description] substringToIndex: 10];
}

Although this kind of brings the model and the view together, the names could be refactored because there is nothing really "column-specific" about this mini-protocol. Also Objective-J has "categories" for grouping methods. The intent of this protocol could be explained by placing the methods in a "presenting" category.

There are certainly more elaborate mechanisms available for keeping views and models separated, yet in-sync. Double Dispatch is just a simple one for reducing the need to test for classes and messages before sending them.

Programming with Cappuccino's CPOutlineView

I wrote in my recent post on Cappuccino about the OK but not great state of documentation. My learning process has been smooth though. I have always had a sense of moving forward with little frustration. But I should attempt to fill some of the documentation gaps myself.

I recently wanted to understand how to program outline views, but ran into some of those gaps. And so my second blog post of the day begins like so.

CPOutlineView is a subclass of CPTableView however from the code using an outline, the requirements are different. Rather than providing a two-dimensional array of data, an application has to provide more of a hierarchy of two-dimensional data. The way I achieve this in my first example is through defining a new class, an SDOutlineController.

(Don't worry about "SD" - that's just the class prefix I am using. Class prefixes are a convention going way back with NeXTStep and before that Smalltalk. Presumably Javascript itself will adopt a conventional if not standard namespace mechanism, and Objective-J can piggyback on that. But I digress...)

This example outline has two groups at the top level: "my stuff" and "other's stuff". Each top-level group has three second-level groups of priorities: "high", "medium", and "low". The third level of the outline are the lists of stuff, themselves. These are arrays of instances of SDStuff.

Here's the class definition for stuff with instance variables for a date, a topic, and notes:

@implementation SDStuff : CPObject
{
  CPDate   date  @accessors(readonly);
  CPString topic @accessors(readonly);
  CPString notes @accessors(readonly);
}

This is Objective-J, a superset of Javascript. I'm assuming that's fairly readable even if you've not programmed in Objective-C and Cocoa. Objective-J can be compiled to Javascript up-front on the server, or in the browser.

The SDOutlineController is the C in MVC for this outline. The V is Cappuccino's CPOutlineView class (and some others). The controller's job is to work with an application's model (the M) in order to present it in the view for user interaction. The model in this case is a little controved, but boils down the essence of a hierarchical model.

I have defined the top-level of the model hierarchy to be a simple class with a label and references to it's children, which group stuff into high, medium, and low priorities:

@implementation SDStuffTopLevel : CPObject
{
  CPString       label                     @accessors(readonly);
  SDStuffParent  highPriorityStuffParent   @accessors(readonly);
  SDStuffParent  mediumPriorityStuffParent @accessors(readonly);
  SDStuffParent  lowPriorityStuffParent    @accessors(readonly);
}

The middle of the hierarchy is similarly defined, but the children are maintained as an array of stuff:

@implementation SDStuffParent : CPObject
{
  CPString label @accessors(readonly);
  CPArray  stuff @accessors(readonly);
}

The model classes above organize data into a fairly simple hierarchical structure. However this structure does not suit all imaginable hierarchies. And so SDOutlineController is designed to avoid having the view depend on any given structure, and vice-versa. The controller has a reference to the top-level for my stuff and the top-level for other's stuff:

@implementation SDOutlineController : CPObject
{
  SDStuffTopLevel myStuffTopLevel;
  SDStuffTopLevel othersStuffTopLevel;
}

The controller has methods expected by CPOutlineView for mediating between the model and the view. The messages are:

  • outlineView:numberOfChildrenOfItem: is kind of obvious.
  • outlineView:isItemExpandable: should be YES (true) if the item has children.
  • outlineView:child:ofItem: should access a hierarchical node's children given an index.
  • outlineView:objectValueForTableColumn:byItem: should provide an object for representing the given model element in the view.

In this example, the top-level of the model always has two elements. The protocol for CPOutlineView uses the convention of passing nil (i.e. the Objective-J equivalent of Javascript's null.) to indicate the root of the model. And so I have not implemented the root as a class.

The following method provides the number of children for any given model element because I have implemented methods for the count message for each model class.

- (int)outlineView:(CPOutlineView)outlineView numberOfChildrenOfItem:(id)item
{
  return (item == nil) ? 2 : [item count];
}

Expandability of a hierarchical element is based on the number of children being greater than zero:

- (BOOL)outlineView:(CPOutlineView)outlineView isItemExpandable:(id)item
{
  return 0 < [self outlineView: outlineView numberOfChildrenOfItem: item];
}

Indexing the child of a hierarchical element is a little more complicated, again just because the root is represented as nil. Otherwise I have implemented objectAtIndex: for the model classes:

- (id)outlineView:(CPOutlineView)outlineView child:(int)index ofItem:(id)item
{
  var result = nil;
  if (nil == item) {
    switch (index) {
    case 0:
      result = myStuffTopLevel;
      break;
    case 1:
      result = othersStuffTopLevel;
      break;
    }
  } else {
    result = [item objectAtIndex: index];
  }
  return result;
}

The remaining method determines the the presentation object for a given model element. The root is never displayed, but to be compelete, this method returns the empty string. Every model class implements objectValueForOutlineColumn: in order to convert itself to its presentation object (which is always a string in this example).

- (id)outlineView:(CPOutlineView)outlineView objectValueForTableColumn:(CPTableColumn)tableColumn byItem:(id)item
{
  return (nil == item) ? @"" : [item objectValueForOutlineColumn: tableColumn];
}

I will use a follow-up blog post to discuss the implementation of objectValueForOutlineColumn:. Perhaps this post provides a little more clarity than other information I've found on the web for programming with CPOutlineView. Let me know if you have a correction or something to add.

On Cappuccino and Avoiding The Modern "Impedance" Mismatch

Wow. My head is just not geared toward writing a blog any longer. But I will model through it.

Cappuccino is a great system for writing rich web applications in the browser, without plugins. There's finally a growing emphasis on Model/View/Controller among modern javascript libraries. Most of them rely on HTML and CSS for the View mechanisms. Which is as you would expect. The problem is the "impedance mismatch" (if you will) between these mechanisms and the desired views for traditional rich applications.

Cappuccino does not suffer such a mismatch, being based on a good portion of the API of NeXTStep, OpenStep, GNUStep, and Apple's Cocoa. And so the Cappuccino API is essentially 25 years old or so.

This choice is not without its pro's and con's. The pro's win for me for applications with these characteristics:

  • At least one display screen greater than 10 inches, i.e. typically used on more than a tablet or phone
  • A good bit more data than would easily fit on a single page, and complex relationships throughout
  • More than a few operations on that data, with a good bit of keyboard input

Because Cappuccino provides an HTML view, this is not a total loss. I've not done much with this yet, but the "con" seems to become a "pro" by allowing for applying HTML and CSS when those mechanisms are the best fit.

Another initial "con" for me the first time I poked at Cappuccino turned "pro" eventually. I'd done a fairly extensive search several months ago on the state of the art of MVC for javascript. Cappuccino was low on my list because I wanted to use javascript per se. Just as Cocoa, et al. are written in Objective-C, Cappuccino is in Objective-J.

I actually like the syntax and class mechanisms, and their similarity to Objective-C and Smalltalk. (Also emacs' Objective-C mode works pretty well as-is with Objective-J.) As the javascript runtimes and tools are adapted to support multiple languages, the tool support for Objective-J should increase.

I came back to Cappuccino after frustration with manipulating HTML and CSS to do my bidding. I don't have any great need for the kind of styling afforded by HTML and CSS. (And with the fallback to an HTML view as per above, even less so.) Most of what I need can be provided satisfactorily using the traditional GUI views going back to Smalltalk-80's MVC.

As it happens, I've done a lot of GUI programming in Smalltalk and several other languages and libraries over the years, so my claim of the pragmatism of this approach also coincides with my experience. Some readers may recall a few years ago that I was in favor of programming web clients using Adobe Flex with ReSTful web services rather than immature javascript/HTML/CSS libraries.

The programmability of views from javascript/HTML/CSS is significantly better now than in 2007. But the majority of libraries are still immature and incomplete. Cappuccino is the best exception to the rule I know of. Fortunately one no longer requires a plugin to achieve Flex's level of productivity.

Cappuccino's class documentation is good, because the API and documentation is already 25 years mature. Tutorials and examples are good, growing, and fortunately supplemented by Cocoa material when the Capp material iteself is lacking.

Friday, July 22, 2011

Kotlin == Harry Potter, Scala == LoTR?

kotlin is a new JVM language, from JetBrains. To understand my title, you may want to read a comparison with Scala from the Kotlin perspective, and some of the discussion taking place in the Scala community.

Perhaps since I recently saw the final Harry Potter movie, the title of this post came immediately to mind. Harry Potter appears to me to be a fun story, whose details exist mainly to support that story. For example, characters seem to have the abilities they require to meet a specific challenge.

On the other hand, the characters in Middle Earth seem be situated in a world that has its own physics. The stories are based on that world, those characters, and the given physics. My understanding is that this is the intention and the process taken to write the books.

Arguably, Harry Potter is far simpler than LoTR. But, arguably, Harry Potter has less to offer than LoTR.

Ten years ago this analogy could have been (and was, essentially) made between Java and Smalltalk. Ten years before *that* the argument had been made between C++ and Smalltalk.

Java is not "pure". Java is in essence Smalltalk but with the "magic" its authors deemed necessary to make Java more successful.

Harry's world is not pure. Middle Earth is (minus some of the complications that can also be found in Smalltalk and Scala.)

Kotlin is a big improvement over Java, but it is merely Java minus some cruft, plus enough magic to be useful in 2011. Scala on the other hand has its own physics that makes sense, and provides for a more rich future than Kotlin.

Hmmm. Just thinking...

Saturday, April 09, 2011

Implementing McCarthy's AMB Operator in Javascript Using a Trampoline

John McCarthy in 1963 wrote about his "AMB" operator for making nondeterministic choices. ("A Basis for a Mathematical Theory of Computation", PDF) AMB is also explained in detail in the (free, online) book Structure and Interpretation of Computer Programs.

AMB provides nondeterministic choices with backtracking in the case of failure. This is one of the major components of logic programming, with unification being the other major component. But AMB is useful even without unification. For example AMB makes it easy to collect all permutations of mutliple choices and to generate selective permutations. (Remember writing permutations as a beginning programmer? Yeah - you probably wish you had been taught AMB ahead of that.)

The SICP book uses Scheme for AMB. Scheme makes this easy, using call/cc and macros. And Common Lisp makes this manageable and pretty using macros. Javascript should not be too bad either - no continuations, no macros, but first-class functions help.

Mihai Bazon recently provided an implementations of AMB in Javascript. (Along with some great examples of using AMB, for example to implement N-Queens and Map Coloring).

Implementing AMB benefits from first-class functions, but they are not necessary. Some mechanism for a dynamic escape is needed. In C this is setjump/longjump. In Javascript (and many other languages) this is throw/catch. C does not have first-class functions, so that part gets ugly. Javascript though is a semi-functional language with first-class functions.

Rather than throw/catch, another versatile way to implement control structures with dynamic extent is to use a trampoline. A few weeks ago I wrote here about NCONC, the core of a Scheme interpreter written in Javascript using a "trampoline" for tail-recursion efficiency as well as for first class continuations.

The project ambjs is an implementation of AMB I wrote in Javascript using a trampoline. The source and the tests are explained using docco.

Using trampolines for dynamic-extent control structures can be cleaner, and they can provide more control options. In the case of AMB this implementation exposes fewer mechanisms than Mihai's, the nesting of AMBs is more apparent (to me), and there are fewer rules to be obeyed (and so fewer opportunities for bugs).

Blog Archive

About Me

Portland, Oregon, United States
I'm usually writing from my favorite location on the planet, the pacific northwest of the u.s. I write for myself only and unless otherwise specified my posts here should not be taken as representing an official position of my employer. Contact me at my gee mail account, username patrickdlogan.