Cardinality and type constraints? #180
-
Hi folks, As an exercise to help learn Logtalk, I'm doing an implementation of the adventure/nani search example, using Logtalk's object oriented features, with an eye toward the actual system I'm building. Representing the data using a class hierarchy is a piece of cake, but I'd like to be able to define and enforce cardinality and type constraints on many of the predicates I'm defining, both at compile time and runtime. Consider this bit of sample code: :- object(thing,
instantiates(thing)).
:- end_object.
:- object(location,
specializes(thing)).
:- dynamic(door_to/1).
:- public(door_to/1).
:- end_object.
:- object(container,
specializes(thing)).
:- end_object.
:- object(room,
specializes([location,container])).
:- public(is_dark/0).
:- end_object.
:- object(item,
specializes(thing)).
:- dynamic(contained_in/1).
:- public(contained_in/1).
:- end_object. Here door_to should be a one-to-many relationship with a range of type location, while contained_in should be a functional relationship with a range of type container. At compile time, I want to throw an error if these constraints are violated in subsequent definitions. At runtime, if a functional relationship (e.g. contained_in) is asserted, I want to intercept that message and potentially retract the previous value before asserting the new one. I've looked for examples of this kind of behavior, and have found the type library, and I can see ways of piecing something together to do what I want, but I imagine this a fairly common pattern, so I figured I'd ask before trying to build an implementation from scratch. Thoughts? Was there a relevant example I missed? |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
One solution is to define predicates that abstract asserting and retracting clauses for those predicates and verify cardinality and type constraints. It may be possible to use Another solution is to use the event-driven programming features: https://logtalk.org/manuals/userman/events.html This allows you to intercept messages, including assert and retract messages, by defining monitors for those events that will verify pre- and post-conditions. See e.g. the There's also a |
Beta Was this translation helpful? Give feedback.
One solution is to define predicates that abstract asserting and retracting clauses for those predicates and verify cardinality and type constraints. It may be possible to use
mode/2
directives for the dynamic/state predicates that declare the necessary cardinality and type constraints. The reflection API allows access to the contents of themode/2
directives at runtime.Another solution is to use the event-driven programming features:
https://logtalk.org/manuals/userman/events.html
This allows you to intercept messages, including assert and retract messages, by defining monitors for those events that will verify pre- and post-conditions. See e.g. the
blocks
example. There's a small perfo…