3455276aa2
git-svn-id: https://yap.svn.sf.net/svnroot/yap/trunk@1487 b08c6af1-5177-4d33-ba66-4b1c6b8b522a
796 lines
22 KiB
Plaintext
796 lines
22 KiB
Plaintext
|
|
:- protocol(relationp).
|
|
|
|
:- info([
|
|
version is 1.0,
|
|
author is 'Paulo Moura',
|
|
date is 2000/7/24,
|
|
comment is 'Relations between objects protocol.']).
|
|
|
|
:- private(tuple_/1).
|
|
:- dynamic(tuple_/1).
|
|
:- mode(tuple_(?list), zero_or_more).
|
|
:- info(tuple_/1, [
|
|
comment is 'Stores the relation tuples.',
|
|
argnames is ['Tuple']]).
|
|
|
|
:- public(tuple/1).
|
|
:- mode(tuple(?list), zero_or_more).
|
|
:- info(tuple/1, [
|
|
comment is 'Returns a relation tuple.',
|
|
argnames is ['Tuple']]).
|
|
|
|
:- public(tuples/1).
|
|
:- mode(tuples(-list), one).
|
|
:- info(tuples/1, [
|
|
comment is 'Returns a list of all relation tuples.',
|
|
argnames is ['Tuples']]).
|
|
|
|
:- public(add_tuple/1).
|
|
:- mode(add_tuple(+list), zero_or_one).
|
|
:- info(add_tuple/1, [
|
|
comment is 'Adds a new relation tuple.',
|
|
argnames is ['Tuple']]).
|
|
|
|
:- public(remove_tuple/1).
|
|
:- mode(remove_tuple(?list), zero_or_more).
|
|
:- info(remove_tuple/1, [
|
|
comment is 'Removes a matching relation tuple.',
|
|
argnames is ['Tuple']]).
|
|
|
|
:- public(remove_all_tuples/0).
|
|
:- mode(remove_all_tuples, one).
|
|
:- info(remove_all_tuples/0, [
|
|
comment is 'Removes all relation tuples.']).
|
|
|
|
:- public(number_of_tuples/1).
|
|
:- mode(number_of_tuples(-integer), one).
|
|
:- info(number_of_tuples/1, [
|
|
comment is 'Returns the current number of relation tuples.',
|
|
argnames is ['Number']]).
|
|
|
|
:- public(plays_role_in_tuple/3).
|
|
:- mode(plays_role_in_tuple(?object, ?atom, ?list), zero_or_more).
|
|
:- info(plays_role_in_tuple/3, [
|
|
comment is 'List of tuples where an object plays a role.',
|
|
argnames is ['Object', 'Role', 'Tuples']]).
|
|
|
|
:- public(plays_roles/2).
|
|
:- mode(plays_roles(?object, -list), zero_or_more).
|
|
:- info(plays_roles/2, [
|
|
comment is 'Returns a list of all roles played by an object in the relation tuples.',
|
|
argnames is ['Object', 'Roles']]).
|
|
|
|
:- public(plays_role_n_times/3).
|
|
:- mode(plays_role_n_times(?object, ?atom, -integer), zero_or_more).
|
|
:- info(plays_role_n_times/3, [
|
|
comment is 'Number of times that an object plays a role in the relation tuples.',
|
|
argnames is ['Object', 'Role', 'Times']]).
|
|
|
|
:- private(domain_/2).
|
|
:- dynamic(domain_/2).
|
|
:- mode(domain_(?atom, ?object), zero_or_more).
|
|
:- info(domain_/2, [
|
|
comment is 'Table of role domains.',
|
|
argnames is ['Role', 'Domain']]).
|
|
|
|
:- public(domains/1).
|
|
:- mode(domains(-list), zero_or_one).
|
|
:- info(domains/1, [
|
|
comment is 'List of domains for all roles.',
|
|
argnames is ['Domains']]).
|
|
|
|
:- public(domain/2).
|
|
:- mode(domain(?atom, ?object), zero_or_more).
|
|
:- info(domain/2, [
|
|
comment is 'Role domain.',
|
|
argnames is ['Role', 'Domain']]).
|
|
|
|
:- public(set_domains/1).
|
|
:- mode(set_domains(+list), zero_or_one).
|
|
:- info(set_domains/1, [
|
|
comment is 'Set the domains for all roles.',
|
|
argnames is ['Domains']]).
|
|
|
|
:- private(descriptor_/1).
|
|
:- dynamic(descriptor_/1).
|
|
:- mode(descriptor_(?list), zero_or_one).
|
|
:- info(descriptor_/1, [
|
|
comment is 'Stores the relation tuple descriptor.',
|
|
argnames is ['Descriptor']]).
|
|
|
|
:- public(descriptor/1).
|
|
:- mode(descriptor(?list), zero_or_one).
|
|
:- info(descriptor/1, [
|
|
comment is 'Returns the relation tuple descriptor.',
|
|
argnames is ['Descriptor']]).
|
|
|
|
:- public(degree/1).
|
|
:- mode(degree(?integer), zero_or_one).
|
|
:- info(degree/1, [
|
|
comment is 'Descriptor length.',
|
|
argnames is ['Degree']]).
|
|
|
|
:- public(set_descriptor/1).
|
|
:- mode(set_descriptor(+list), zero_or_one).
|
|
:- info(set_descriptor/1, [
|
|
comment is 'Sets the relation tuple descriptor.',
|
|
argnames is ['Descriptor']]).
|
|
|
|
:- private(key_/1).
|
|
:- dynamic(key_/1).
|
|
:- mode(key_(?list), zero_or_more).
|
|
:- info(key_/1, [
|
|
comment is 'Stores the relation keys.',
|
|
argnames is ['Key']]).
|
|
|
|
:- public(key/1).
|
|
:- mode(key(?list), zero_or_more).
|
|
:- info(key/1, [
|
|
comment is 'Returns a relation key.',
|
|
argnames is ['Key']]).
|
|
|
|
:- public(keys/1).
|
|
:- mode(keys(-list), one).
|
|
:- info(keys/1, [
|
|
comment is 'Returns a list of all relation keys.',
|
|
argnames is ['Keys']]).
|
|
|
|
:- public(set_keys/1).
|
|
:- mode(set_keys(+list), zero_or_one).
|
|
:- info(set_keys/1, [
|
|
comment is 'Sets the relation keys.',
|
|
argnames is ['Keys']]).
|
|
|
|
:- private(delete_option_/2).
|
|
:- dynamic(delete_option_/2).
|
|
:- mode(delete_option_(?atom, ?atom), zero_or_more).
|
|
:- info(delete_option_/2, [
|
|
comment is 'Stores role delete options.',
|
|
argnames is ['Role', 'Option']]).
|
|
|
|
:- public(delete_options/1).
|
|
:- mode(delete_options(-list), zero_or_one).
|
|
:- info(delete_options/1, [
|
|
comment is 'Returns a list of all role - delete option pairs.',
|
|
argnames is ['Options']]).
|
|
|
|
:- public(delete_option/2).
|
|
:- mode(delete_option(?atom, ?atom), zero_or_more).
|
|
:- info(delete_option/2, [
|
|
comment is 'Returns role delete options.',
|
|
argnames is ['Role', 'Option']]).
|
|
|
|
:- public(set_delete_options/1).
|
|
:- mode(set_delete_options(+list), zero_or_one).
|
|
:- info(set_delete_options/1, [
|
|
comment is 'Sets the roles delete options.',
|
|
argnames is ['Options']]).
|
|
|
|
:- private(cardinality_/3).
|
|
:- dynamic(cardinality_/3).
|
|
:- mode(cardinality_(?atom, ?nonvar, ?nonvar), zero_or_more).
|
|
:- info(cardinality_/3, [
|
|
comment is 'Table of roles minimum and maximum cardinalities.',
|
|
argnames is ['Role', 'Min', 'Max']]).
|
|
|
|
:- public(cardinalities/1).
|
|
:- mode(cardinalities(-list), zero_or_one).
|
|
:- info(cardinalities/1, [
|
|
comment is 'List of minimum and maximum cardinalities of all roles.',
|
|
argnames is ['Cardinalities']]).
|
|
|
|
:- public(cardinality/3).
|
|
:- mode(cardinality(?atom, ?nonvar, ?nonvar), zero_or_more).
|
|
:- info(cardinality/3, [
|
|
comment is 'Role minimum and maximum cardinalities.',
|
|
argnames is ['Role', 'Min', 'Max']]).
|
|
|
|
:- public(set_cardinalities/1).
|
|
:- mode(set_cardinalities(+list), zero_or_one).
|
|
:- info(cardinalities/1, [
|
|
comment is 'Sets the minimum and maximum cardinalities of all roles.',
|
|
argnames is ['Cardinalities']]).
|
|
|
|
:- protected(set_monitors/1).
|
|
:- mode(set_monitors(+list), one).
|
|
|
|
:- protected(del_all_monitors/0).
|
|
:- mode(del_all_monitors, one).
|
|
|
|
:- protected(del_monitors/1).
|
|
:- mode(del_monitors(+list), one).
|
|
|
|
:- protected(restore_monitors/0).
|
|
:- mode(restore_monitors, zero_or_one).
|
|
|
|
:- end_protocol.
|
|
|
|
|
|
|
|
:- object(relation,
|
|
implements(relationp),
|
|
instantiates(class),
|
|
specializes(object)).
|
|
|
|
:- info([
|
|
version is 1.2,
|
|
date is 2004/8/15,
|
|
author is 'Esteban Zimanyi, Paulo Moura',
|
|
comment is 'Enables the representation of relations between independent objects.']).
|
|
|
|
:- uses(before_event_registry).
|
|
:- uses(after_event_registry).
|
|
:- uses(list,
|
|
[length/2, member/2, memberchk/2, nth1/3, same_length/2]).
|
|
|
|
tuple(Tuple) :-
|
|
::tuple_(Tuple).
|
|
|
|
tuples(Tuples) :-
|
|
findall(Tuple, ::tuple_(Tuple), Tuples).
|
|
|
|
add_tuple(Tuple) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::add_tuple(Tuple), Sender)).
|
|
|
|
add_tuple(Tuple) :-
|
|
::descriptor(Descriptor),
|
|
\+ same_length(Tuple, Descriptor),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(invalid_length, Self::add_tuple(Tuple), Sender)).
|
|
|
|
add_tuple(Tuple) :-
|
|
::descriptor(Descriptor),
|
|
::key(Key),
|
|
make_tuple_template(Tuple, Descriptor, Key, Template),
|
|
::tuple(Template),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(breaks_key(Key), Self::add_tuple(Tuple), Sender)).
|
|
|
|
add_tuple(Tuple) :-
|
|
::descriptor(Descriptor),
|
|
nth1(Position, Tuple, Object),
|
|
nth1(Position, Descriptor, Role),
|
|
::cardinality(Role, _, Maximum),
|
|
::plays_role_n_times(Object, Role, Number),
|
|
Maximum = Number,
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(breaks_max_cardinality(Object, Role, Maximum), Self::add_tuple(Tuple), Sender)).
|
|
|
|
add_tuple(Tuple) :-
|
|
::descriptor(Descriptor),
|
|
nth1(Position, Tuple, Object),
|
|
nth1(Position, Descriptor, Role),
|
|
::domain(Role, Domain),
|
|
(Domain::strict_instance ->
|
|
\+ Domain::valid(Object)
|
|
;
|
|
\+ Object::ancestor(Domain)),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(breaks_domain(Object, Role, Domain), Self::add_tuple(Tuple), Sender)).
|
|
|
|
add_tuple(Tuple) :-
|
|
::assertz(tuple_(Tuple)),
|
|
::set_monitors(Tuple).
|
|
|
|
|
|
make_tuple_template([], [], _, []).
|
|
make_tuple_template([Object| Objects], [Role| Roles], Key, [Var| Rest]) :-
|
|
(member(Role, Key) ->
|
|
Var = Object
|
|
;
|
|
true),
|
|
make_tuple_template(Objects, Roles, Key, Rest).
|
|
|
|
remove_tuple(Tuple) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::remove_tuple(Tuple), Sender)).
|
|
|
|
remove_tuple(Tuple) :-
|
|
::descriptor(Descriptor),
|
|
nth1(Position, Tuple, Object),
|
|
nth1(Position, Descriptor, Role),
|
|
::cardinality(Role, Minimum, _),
|
|
::plays_role_n_times(Object, Role, Number),
|
|
Minimum = Number,
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(breaks_min_cardinality(Object, Role, Minimum), Self::remove_tuple(Tuple), Sender)).
|
|
|
|
remove_tuple(Tuple) :-
|
|
::retract(tuple_(Tuple)),
|
|
::del_monitors(Tuple).
|
|
|
|
remove_all_tuples :-
|
|
::retractall(tuple_(_)),
|
|
::del_all_monitors.
|
|
|
|
number_of_tuples(Number) :-
|
|
findall(1, ::tuple_(_), List),
|
|
length(List, Number).
|
|
|
|
plays_roles(Object, Roles) :-
|
|
::descriptor(Descriptor),
|
|
setof(Role,
|
|
Tuple^Position^ (::tuple(Tuple),
|
|
member(Object, Tuple),
|
|
nth1(Position, Tuple, Object),
|
|
once(nth1(Position, Descriptor, Role))),
|
|
Roles).
|
|
|
|
plays_role_in_tuple(Object, Role, Tuple) :-
|
|
::descriptor(Descriptor),
|
|
::tuple(Tuple),
|
|
nth1(Position, Tuple, Object),
|
|
nth1(Position, Descriptor, Role).
|
|
|
|
plays_role_n_times(Object, Role, Number) :-
|
|
::descriptor(Descriptor),
|
|
nth1(Position, Descriptor, Role),
|
|
setof(Tuple,
|
|
(::tuple(Tuple),
|
|
nth1(Position, Tuple, Object)),
|
|
Tuples),
|
|
length(Tuples, Number).
|
|
|
|
domains(Domains) :-
|
|
::descriptor(Descriptor),
|
|
domains(Descriptor, Domains).
|
|
|
|
domains([], []).
|
|
domains([Role| Roles], [Domain| Domains]) :-
|
|
::domain_(Role, Domain),
|
|
domains(Roles, Domains).
|
|
|
|
domain(Role, Domain) :-
|
|
::domain_(Role, Domain).
|
|
|
|
set_domains(Domains) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::set_domains(Domains), Sender)).
|
|
|
|
set_domains(Domains) :-
|
|
::tuple(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(non_empty_relation, Self::set_domains(Domains), Sender)).
|
|
|
|
set_domains(Domains) :-
|
|
::descriptor(Descriptor),
|
|
set_domains(Domains, Descriptor).
|
|
|
|
|
|
set_domains([], []).
|
|
set_domains([Role| Roles], [Domain| Domains]) :-
|
|
::retractall(domain_(Role, _)),
|
|
::assertz(domain_(Role, Domain)),
|
|
set_domains(Roles, Domains).
|
|
|
|
descriptor(Descriptor) :-
|
|
::descriptor_(Descriptor).
|
|
|
|
degree(Degree) :-
|
|
::descriptor_(Descriptor),
|
|
length(Descriptor, Degree).
|
|
|
|
set_descriptor(Descriptor) :-
|
|
\+ ::tuple(_),
|
|
::assertz(descriptor_(Descriptor)),
|
|
::set_keys([Descriptor]),
|
|
set_role_defaults(Descriptor).
|
|
|
|
set_role_defaults([]).
|
|
set_role_defaults([Role| Roles]) :-
|
|
::set_domain(Role, object),
|
|
::set_cardinality(Role, 0, n),
|
|
::set_delete_option(Role, cascade),
|
|
set_role_defaults(Roles).
|
|
|
|
key(Key) :-
|
|
::key_(Key).
|
|
|
|
keys(Keys) :-
|
|
findall(Key, ::key_(Key), Keys).
|
|
|
|
set_keys(Keys) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::set_keys(Keys), Sender)).
|
|
|
|
set_keys(Keys) :-
|
|
::tuple(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(non_empty_relation, Self::set_keys(Keys), Sender)).
|
|
|
|
set_keys(Keys) :-
|
|
\+ valid_keys(Keys),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(invalid_key, Self::set_keys(Keys), Sender)).
|
|
|
|
set_keys(Keys) :-
|
|
::retractall(key_(_)),
|
|
set_keys2(Keys).
|
|
|
|
set_keys2([]).
|
|
set_keys2([Key| Keys]) :-
|
|
::assertz(key_(Key)),
|
|
set_keys2(Keys).
|
|
|
|
valid_keys(Keys) :-
|
|
::descriptor(Descriptor),
|
|
valid_keys(Keys, Descriptor).
|
|
|
|
valid_keys([], _).
|
|
valid_keys([Key| Keys], Descriptor) :-
|
|
forall(
|
|
member(Role, Key),
|
|
memberchk(Role, Descriptor)),
|
|
valid_keys(Keys, Descriptor).
|
|
|
|
delete_options(Options) :-
|
|
::descriptor(Descriptor),
|
|
delete_options(Descriptor, Options).
|
|
|
|
delete_options([], []).
|
|
delete_options([Role| Roles], [Option| Options]) :-
|
|
::delete_option_(Role, Option),
|
|
delete_options(Roles, Options).
|
|
|
|
delete_option(Role, Option) :-
|
|
::delete_option_(Role, Option).
|
|
|
|
set_delete_options(Options) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::set_delete_options(Options), Sender)).
|
|
|
|
set_delete_options(Options) :-
|
|
::tuple(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(non_empty_relation, Self::set_delete_options(Options), Sender)).
|
|
|
|
set_delete_options(Options) :-
|
|
::descriptor(Descriptor),
|
|
\+ same_length(Options, Descriptor),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(invalid_length, Self::set_delete_options(Options), Sender)).
|
|
|
|
set_delete_options(Options) :-
|
|
\+ valid_delete_options(Options),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(invalid_delete_option, Self::set_delete_options(Options), Sender)).
|
|
|
|
set_delete_options(Options) :-
|
|
::descriptor(Descriptor),
|
|
set_delete_options(Descriptor, Options).
|
|
|
|
set_delete_options([], []).
|
|
set_delete_options([Role| Roles], [Option| Options]) :-
|
|
::retractall(delete_option_(Role, _)),
|
|
::assertz(delete_option_(Role, Option)),
|
|
set_delete_options(Roles, Options).
|
|
|
|
valid_delete_options([]).
|
|
valid_delete_options([Option| Options]) :-
|
|
once((Option = restrict; Option = cascade)),
|
|
valid_delete_options(Options).
|
|
|
|
cardinalities(Cardinalities) :-
|
|
::descriptor(Descriptor),
|
|
cardinalities(Descriptor, Cardinalities).
|
|
|
|
cardinalities([], []).
|
|
cardinalities([Role| Roles], [(Min, Max)| Cardinalities]) :-
|
|
::cardinality_(Role, Min, Max),
|
|
cardinalities(Roles, Cardinalities).
|
|
|
|
cardinality(Role, Min, Max) :-
|
|
::cardinality_(Role, Min, Max).
|
|
|
|
set_cardinalities(Cardinalities) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::set_cardinalities(Cardinalities), Sender)).
|
|
|
|
set_cardinalities(Cardinalities) :-
|
|
::tuple(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(non_empty_relation, Self::set_cardinalities(Cardinalities), Sender)).
|
|
|
|
set_cardinalities(Cardinalities) :-
|
|
\+ valid_cardinalities(Cardinalities),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(invalid_cardinality, Self::set_cardinalities(Cardinalities), Sender)).
|
|
|
|
set_cardinalities(Cardinalities) :-
|
|
::descriptor(Descriptor),
|
|
set_cardinalities(Cardinalities, Descriptor).
|
|
|
|
|
|
set_cardinalities([], []).
|
|
set_cardinalities([(Min, Max)| Cardinalities], [Role| Roles]) :-
|
|
::retractall(cardinality_(Role, _, _)),
|
|
::assertz(cardinality_(Role, Min, Max)),
|
|
set_cardinalities(Cardinalities, Roles).
|
|
|
|
valid_cardinalities([]).
|
|
valid_cardinalities([Cardinality| Cardinalities]) :-
|
|
nonvar(Cardinality),
|
|
Cardinality = (Min, Max),
|
|
lower_cardinality(Min, Max),
|
|
valid_cardinalities(Cardinalities).
|
|
|
|
lower_cardinality(I, n) :-
|
|
integer(I), !.
|
|
lower_cardinality(I, J) :-
|
|
integer(I),
|
|
integer(J),
|
|
I < J.
|
|
|
|
free(Options) :-
|
|
::remove_all_tuples,
|
|
^^free(Options).
|
|
|
|
set_monitors([]).
|
|
set_monitors([Object| Objects]) :-
|
|
(instantiates_class(Object, Class) ->
|
|
self(Self),
|
|
before_event_registry::set_monitor(Class, delete(Object, _), _, Self)
|
|
;
|
|
true),
|
|
set_monitors(Objects).
|
|
|
|
del_monitors([]).
|
|
del_monitors([Object| Objects]) :-
|
|
((instantiates_class(Object, Class),
|
|
\+ (::tuple(Other), member(Object, Other))) ->
|
|
self(Self),
|
|
before_event_registry::del_monitors(Class, delete(Object, _), _, Self)
|
|
;
|
|
true),
|
|
del_monitors(Objects).
|
|
|
|
del_all_monitors :-
|
|
self(Self),
|
|
before_event_registry::del_monitors(_, _, _, Self),
|
|
after_event_registry::del_monitors(_, _, _, Self).
|
|
|
|
before(_, delete(Object, Options), _) :-
|
|
!,
|
|
((::delete_option(Role, restrict),
|
|
::plays_role_in_tuple(Object, Role, Tuple)) ->
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(can_not_be_deleted(Tuple, Object, Role), Self::delete(Object, Options), Sender))
|
|
;
|
|
forall(
|
|
::plays_role_in_tuple(Object, Role, Tuple),
|
|
::remove_tuple(Tuple))).
|
|
|
|
before(_, _, _).
|
|
|
|
after(_, _, _).
|
|
|
|
restore_monitors :-
|
|
self(Self),
|
|
before_event_registry::del_monitors(_, _, _, Self),
|
|
after_event_registry::del_monitors(_, _, _, Self),
|
|
forall(::tuple(Tuple), ::set_monitors(Tuple)).
|
|
|
|
print :-
|
|
::descriptor(Descriptor),
|
|
write('descriptor:'), nl, write(' '), writeq(Descriptor), nl,
|
|
::domains(Domains),
|
|
write('domains:'), nl, write(' '), writeq(Domains), nl,
|
|
::cardinalities(Cardinalities),
|
|
write('cardinalities:'), nl, write(' '), writeq(Cardinalities), nl,
|
|
::delete_options(Options),
|
|
write('delete options:'), nl, write(' '), writeq(Options), nl,
|
|
write('keys:'), nl,
|
|
forall(::key(Key), (write(' '), writeq(Key), nl)),
|
|
write('tuples:'), nl,
|
|
forall(::tuple(Tuple), (write(' '), writeq(Tuple), nl)).
|
|
|
|
:- end_object.
|
|
|
|
|
|
|
|
:- object(constrained_relation,
|
|
instantiates(class),
|
|
specializes(relation)).
|
|
|
|
:- info([
|
|
version is 3.2,
|
|
date is 2005/1/29,
|
|
author is 'Paulo Moura',
|
|
comment is 'Enables the representation of relations with constraints on the state of participating objects.']).
|
|
|
|
:- uses(list,
|
|
[member/2, memberchk/2, subtract/3]).
|
|
|
|
:- private(activ_points_/3).
|
|
:- dynamic(activ_points_/3).
|
|
:- mode(activ_points_(?atom, ?event, -list), zero_or_more).
|
|
|
|
:- public(activ_point/3).
|
|
:- mode(activ_point(?atom, ?event, ?callable), zero_or_more).
|
|
|
|
:- public(activ_points/3).
|
|
:- mode(activ_points(?atom, ?event, -list), zero_or_more).
|
|
|
|
:- public(set_activ_points/3).
|
|
:- mode(set_activ_points(+atom, +event, +list), one).
|
|
|
|
:- protected(unique_messages/4).
|
|
:- mode(unique_messages(+list, +atom, +event, -list), one).
|
|
|
|
:- protected(propagate/5).
|
|
:- mode(propagate(+atom, +callable, +object, +atom, +list), zero_or_one).
|
|
|
|
before(Object, Message, Sender) :-
|
|
self(Self),
|
|
(Self \= Sender ->
|
|
forall(
|
|
(::activ_point(Role, before, Message),
|
|
::plays_role_in_tuple(Object, Role, Tuple)),
|
|
::propagate(before, Message, Object, Role, Tuple))
|
|
;
|
|
true),
|
|
^^before(Object, Message, Sender).
|
|
|
|
after(Object, Message, Sender) :-
|
|
self(Self),
|
|
(Self \= Sender ->
|
|
forall(
|
|
(::activ_point(Role, after, Message),
|
|
::plays_role_in_tuple(Object, Role, Tuple)),
|
|
::propagate(after, Message, Object, Role, Tuple))
|
|
;
|
|
true),
|
|
^^after(Object, Message, Sender).
|
|
|
|
set_monitors(Tuple) :-
|
|
^^set_monitors(Tuple),
|
|
::descriptor(Descriptor),
|
|
set_monitors(Tuple, Descriptor).
|
|
|
|
set_monitors([], []).
|
|
set_monitors([Object| Objects], [Role| Roles]) :-
|
|
once(::activ_points(Role, before, Messages1)), % avoid spurious backtracking
|
|
set_object_before_monitors(Messages1, Object),
|
|
once(::activ_points(Role, after, Messages2)), % avoid spurious backtracking
|
|
set_object_after_monitors(Messages2, Object),
|
|
set_monitors(Objects, Roles).
|
|
|
|
set_object_before_monitors([], _).
|
|
set_object_before_monitors([Message| Messages], Object) :-
|
|
self(Self),
|
|
before_event_registry::set_monitor(Object, Message, _, Self),
|
|
set_object_before_monitors(Messages, Object).
|
|
|
|
set_object_after_monitors([], _).
|
|
set_object_after_monitors([Message| Messages], Object) :-
|
|
self(Self),
|
|
after_event_registry::set_monitor(Object, Message, _, Self),
|
|
set_object_after_monitors(Messages, Object).
|
|
|
|
del_monitors(Tuple) :-
|
|
^^del_monitors(Tuple),
|
|
::descriptor(Descriptor),
|
|
del_monitors(Tuple, Descriptor).
|
|
|
|
del_monitors([], []).
|
|
del_monitors([Object| Objects], [Role| Roles]) :-
|
|
del_object_monitors(Object, Role),
|
|
del_monitors(Objects, Roles).
|
|
|
|
del_object_monitors(Object, Role) :-
|
|
::plays_roles(Object, Roles) ->
|
|
(member(Role, Roles) ->
|
|
true
|
|
;
|
|
del_object_monitors(Object, Role, Roles))
|
|
;
|
|
del_object_monitors(Object, Role, []).
|
|
|
|
del_object_monitors(Object, Role, Roles) :-
|
|
::unique_messages(Roles, Role, before, Messages1),
|
|
del_object_before_monitors(Messages1, Object),
|
|
::unique_messages(Roles, Role, after, Messages2),
|
|
del_object_after_monitors(Messages2, Object).
|
|
|
|
del_object_before_monitors([], _).
|
|
del_object_before_monitors([Message| Messages], Object) :-
|
|
self(Self),
|
|
before_event_registry::del_monitors(Object, Message, _, Self),
|
|
del_object_before_monitors(Messages, Object).
|
|
|
|
del_object_after_monitors([], _).
|
|
del_object_after_monitors([Message| Messages], Object) :-
|
|
self(Self),
|
|
after_event_registry::del_monitors(Object, Message, _, Self),
|
|
del_object_after_monitors(Messages, Object).
|
|
|
|
propagate(Event, Message, Object, Role, Tuple) :-
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(desc_responsibility, Self::propagate(Event, Message, Object, Role, Tuple), Sender)).
|
|
|
|
activ_point(Role, Event, Message) :-
|
|
::activ_points_(Role, Event, Messages),
|
|
member(Message, Messages).
|
|
|
|
activ_points(Role, Event, List) :-
|
|
::activ_points_(Role, Event, List).
|
|
|
|
set_activ_points(Role, Event, List) :-
|
|
\+ ::descriptor(_),
|
|
self(Self),
|
|
sender(Sender),
|
|
throw(error(descriptor_not_defined, Self::set_activ_points(Role, Event, List), Sender)).
|
|
|
|
set_activ_points(Role, Event, List) :-
|
|
::descriptor(Descriptor),
|
|
memberchk(Role, Descriptor),
|
|
::retractall(activ_points_(Role, Event, _)),
|
|
::assertz(activ_points_(Role, Event, List)).
|
|
|
|
unique_messages(Roles, Role, Event, Messages) :-
|
|
::activ_points_(Role, Event, Original),
|
|
filter_messages(Roles, Original, Event, Messages).
|
|
|
|
filter_messages([], Messages, _, Messages).
|
|
filter_messages([Role| Roles], Original, Event, Messages) :-
|
|
::activ_points_(Role, Event, Excluded),
|
|
subtract(Original, Excluded, Rest),
|
|
filter_messages(Roles, Rest, Event, Messages).
|
|
|
|
set_descriptor(Descriptor) :-
|
|
^^set_descriptor(Descriptor),
|
|
set_default_activ_points(Descriptor).
|
|
|
|
set_default_activ_points([]).
|
|
set_default_activ_points([Role| Roles]) :-
|
|
::set_activ_points(Role, before, []),
|
|
::set_activ_points(Role, after, []),
|
|
set_default_activ_points(Roles).
|
|
|
|
print :-
|
|
^^print,
|
|
::descriptor(Descriptor),
|
|
write('call activation points:'), nl,
|
|
findall(Messages,
|
|
(member(Role, Descriptor),
|
|
::activ_points(Role, before, Messages)),
|
|
CallList),
|
|
write(' '), writeq(CallList), nl,
|
|
write('exit activation points:'), nl,
|
|
findall(Messages,
|
|
(member(Role, Descriptor),
|
|
::activ_points(Role, after, Messages)),
|
|
ExitList),
|
|
write(' '), writeq(ExitList), nl.
|
|
|
|
:- end_object.
|