Recently I read two papers that dealt with different strategies for integrating Smalltalk and PROLOG.
This paper concerns intelligent planning and design tasks. The researchers used Prolog to encode the interpretation of user-given constraint rules for a task that ought to be carried out, with predicates stored as objects via a dynamic Smalltalk database, with an API for communication between them. Smalltalk would send requests to PROLOG of the form ‘solve this planning problem’ by invoking predefined predicates, which would in turn provide solution terms. Smalltalk would interpret and display these solution terms. PROLOG acted as a black box solver.
This made use of PROLOG’s tracing capabilities for justification purposes I.E., explaining why the system came to the solutions which it did, and how they matched the user’s preferences. This was thus an early demonstration of a heterogeneous planning architecture. The authors cite that user interfaces are ‘unnatural’ to define declaratively and say there is ‘more evidence’ for OOP being a better fit for configuration tasks. They also suggest the option of building a PROLOG interpreter within Smalltalk, but seemed to discard this option since it was out of scope of their interests.
This paper concerns the definition of a model for logic programming within an object-oriented framework called the ‘Alltalk Logic Facility’ taking inspirations from earlier work on LOGIN, which models the inheritance model as an application of lattice theory. Regular PROLOG terms are replaced with ‘structured’ terms which allows for the labelling of attributes, as well as specification of given inheritance relationships.
For example, inheritance might be represented as such
default(person, language, english).
default(italian_person, language, italian).
italian_person :: person.
It is clear from this that italian people are (at least for the purpose of this program) a subset of people.
italian_person⊑ person
Upon querying
?- italian_person(name: mario, age: 30).
The system would be able to compute that the language is Italian by referring to the relevant inheritance relationships. This, in my opinion, vindicates the view that there is some natural bridge to be made between objects and SLD resolution. However it is worth noting that in LOGIN, non-monotonicity is implied, since something can be default at one point, and then populated later, which would invalidate previous queries. It’s also worth noting that whereas ALF is constructed within a Smalltalk environment, LOGIN was implemented in PROLOG.
As an aside, I found this paper particularly interesting because of work @mariari and I have done in the past within Logtalk on the representation and computation of sets and topologies, in which I concluded that for topologies to be represented well in a declarative OO model (I.E., to uphold completeness) that either normalisation and partial-ordering of terms might be required, and I thought maybe lattice theory could be of help.
Conclusion
One of these papers deals with external integration of PROLOG within Smalltalk, and the other deals with internal integration where-in the logic system is extended with object structure. They are orthogonal strategies. One in my opinion (the former) is much easier to implement within existing systems, but the latter is more coherent. Both validate the view that there is some natural cohesiveness between the two.
Looking ahead, I think more work should be done looking into reconciling dynamic declarative OO systems with non-monotonicity and structured fallbacks. I also think more investigation needs to be done into the first paper’s claim that UIs are unnatural for the declarative style-- more specifically whether this would extend to a declarative object style, as I think being able to access the declarative style would confer advantages. XPCE (an old WIMP GUI builder for PROLOG) uses method invocation (calls C++) and looks like
**:- pce_begin_class(text_box, device).
initialise(Node, Name:string) :->
send_super(Node, initialise),
new(Label, text(Name, center)),
send(Label, colour, black),
get(Label, width, W),
get(Label, height, H),
send(Label, center, point(0, 0)),
new(Box, box(W+10, H+10)),
send(Box, colour, black),
send(Box, fill_pattern, colour(white)),
send(Node, display, Box, point(-W/2-5, -H/2-5)),
send(Node, display, Label).
:- pce_end_class.
**
I think there are ways this could be quite nice actually if it wasn’t for some of the IMO unnecessary get/send predicates that are likely a consequence of the API, and I think the declarative style could be quite useful in UI design.