📄 oaa.pl
字号:
% When specifying addresses, in address/1 params for calls to
% oaa_AddData, oaa_Solve, etc., either names or addresses may be used.
% In addition, for convenience, reserved terms 'self', 'parent', and
% 'facilitator' may also be used.
%
% More precisely, the address parameter may contain any of the following:
% a full address; a local ID (when the addressee is known to be
% a peer client); a name, enclosed in the name/1 functor;
% 'self'; 'parent'; or 'facilitator'. ('parent' and 'facilitator are
% synonymous.)
%
% Address parameters are standardized as follows: local IDs are changed to
% full addresses, relative to the 'fac_listener' connection (for a root
% or node agent), or to the 'parent' connection (for a leaf).
% Full addresses are left as is. Names are left as is, but ensuring they're
% enclosed within name/1. 'self',
% 'parent', and 'facilitator' are changed to the appropriate full address.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% This can only be used AFTER oaa_SetupCommunication has been called,
% because of the reliance here on com:com_connection_info/5.
icl_standardize_address(Addr, SAddr) :-
\+ is_list(Addr),
!,
icl_standardize_address([Addr], SAddr).
icl_standardize_address([], []).
icl_standardize_address([Addr | Addrs], [SAddr | SAddrs]) :-
icl_standardize_addressee(Addr, SAddr),
!,
icl_standardize_address(Addrs, SAddrs).
icl_standardize_address([_Addr | Addrs], SAddrs) :-
icl_standardize_address(Addrs, SAddrs).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
icl_standardize_addressee(self, Addr) :-
oaa_PrimaryAddress(Addr),
!.
icl_standardize_addressee(parent, Addr) :-
com:com_GetInfo(parent, other_address(Addr)),
!.
icl_standardize_addressee(facilitator, Addr) :-
com:com_GetInfo(parent, other_address(Addr)),
!.
icl_standardize_addressee(addr(Fac), addr(FacStandard)) :-
!,
com:com_StandardizeAddress(Fac, FacStandard).
icl_standardize_addressee(addr(FacAddr, Id), addr(FacStandard)) :-
icl_fac_id(Id),
!,
com:com_StandardizeAddress(FacAddr, FacStandard).
icl_standardize_addressee(addr(FacAddr, Id), addr(FacStandard, Id)) :-
!,
com:com_StandardizeAddress(FacAddr, FacStandard).
icl_standardize_addressee(Id, Addr) :-
icl_fac_id(Id),
com:com_GetInfo(fac_listener, oaa_address(Addr)),
!.
icl_standardize_addressee(Id, Addr) :-
icl_fac_id(Id),
com:com_GetInfo(parent, other_address(Addr)),
!.
icl_standardize_addressee(Id, addr(Addr, Id)) :-
icl_id(Id),
com:com_GetInfo(fac_listener, oaa_address(addr(Addr))),
!.
icl_standardize_addressee(Id, addr(Addr, Id)) :-
icl_id(Id),
com:com_GetInfo(parent, other_address(addr(Addr))),
!.
icl_standardize_addressee(name(Name), name(Name)) :-
!,
icl_name(Name).
icl_standardize_addressee(Name, name(Name)) :-
icl_name(Name),
!,
format('~w (~w): addressee name, in address/1 param, should be specified as:~n name(~w)~n',
['WARNING', 'oaa.pl', Name]).
icl_standardize_addressee(Whatever, _) :-
format('~w (~w): Illegal addressee, in address/1 param, discarded:~n ~w~n',
['WARNING', 'oaa.pl', Whatever]),
fail.
icl_id(Num) :-
integer(Num),
Num >= 0.
icl_fac_id(0).
icl_address_to_id(addr(_FacAddr, Id), Id) :-
!.
icl_address_to_id(_, Id) :-
icl_fac_id(Id).
icl_name(self) :-
!, fail.
icl_name(parent) :-
!, fail.
icl_name(facilitator) :-
!, fail.
icl_name(Atom) :-
atom(Atom).
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name: icl_ConvertSolvables(+ShorthandSolvables, -StandardSolvables).
% icl_ConvertSolvables(-ShorthandSolvables, +StandardSolvables).
%
% purpose: Convert between shorthand and standard forms of solvables list.
% remarks:
% - In the standard form, each element is a term solvable(Goal,
% Params, Permissions), with Permissions and Params both lists.
% In the Permissions and Params lists, values appear only when they
% are OTHER than the default.
% - In the shorthand form, each element can be solvable/3, as above,
% or solvable(Goal, Params), or solvable(Goal), or just Goal.
% - Note that "shorthand" means "anything goes" - so shorthand
% solvables are a superset of standard solvables.
% - Permissions (defaults in square brackets):
% call(T_F) [true], read(T_F) [false], write(T_F) [false]
% - Params (defaults in square brackets):
% type(Data_Procedure_Trigger) [procedure],
% callback(Functor) [no default]
% utility(N) [5]
% synonym(SynonymHead, RealHead) [none]
% rules_ok(T_F) [false],
% single_value(T_F) [false],
% unique_values(T_F) [false],
% private(T_F) [false]
% bookkeeping(T_F) [true]
% persistent(T_F) [false]
% filename(FileName) [none] : only for data predicates, can specify a save/load file
% - Refer to Agent Library Reference Manual for details on Permissions
% and Params.
% - (TBD) This might be the place to check the validity of solvables,
% such as using only built-ins in tests. Also, check for dependencies
% between solvables; e.g., when persistent(false) is there,
% bookkeeping(true) must also be there.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
icl_ConvertSolvables(ShorthandSolvables, StandardSolvables) :-
var(StandardSolvables),
!,
icl_standardize_solvables(ShorthandSolvables, StandardSolvables).
icl_ConvertSolvables(ShorthandSolvables, StandardSolvables) :-
icl_readable_solvables(StandardSolvables, ShorthandSolvables).
% icl_standardize_solvables(+ShorthandSolvables,
% -StandardSolvables).
icl_standardize_solvables([], []).
icl_standardize_solvables([Shorthand | RestSH], [Standard | RestStan]) :-
icl_standardize_solvable(Shorthand, Standard),
icl_standardize_solvables(RestSH, RestStan).
% icl_standardize_solvable(+Shorthand, -Standard).
icl_standardize_solvable(solvable((Goal :- Test), Params, Perms), Standard) :-
!,
append([test(Test)], Params, NewParams),
icl_standardize_solvable(solvable(Goal, NewParams, Perms), Standard).
icl_standardize_solvable(solvable((Goal :- Test), Params), Standard) :-
!,
icl_standardize_solvable(solvable(Goal, [test(Test) | Params], []),
Standard).
icl_standardize_solvable(solvable((Goal :- Test)), Standard) :-
!,
icl_standardize_solvable(solvable(Goal, [test(Test)], []), Standard).
icl_standardize_solvable((Goal :- Test), Standard) :-
!,
icl_standardize_solvable(solvable(Goal, [test(Test)], []), Standard).
icl_standardize_solvable(solvable(Goal, Params, Perms),
solvable(Goal, NewParams, NewPerms)) :-
!,
icl_standardize_params(Params, false, NewParams),
icl_standardize_perms(Perms, false, NewPerms).
icl_standardize_solvable(solvable(Goal, Params),
solvable(Goal, NewParams, [])) :-
!,
icl_standardize_params(Params, false, NewParams).
icl_standardize_solvable(solvable(Goal), solvable(Goal, [], [])) :- !.
icl_standardize_solvable(Goal, solvable(Goal, [], [])) :- !.
% icl_readable_solvables(+StandardSolvables,
% -ShorthandSolvables).
% This is provided for use in "pretty-printing" solvables, in trace
% messages, etc.
icl_readable_solvables([], []).
icl_readable_solvables([Standard | RestStan], [Shorthand | RestSh]) :-
icl_readable_solvable(Standard, Shorthand),
icl_readable_solvables(RestStan, RestSh).
% icl_readable_solvable(+Standard, -Shorthand).
icl_readable_solvable(solvable(Goal, [], []), Goal) :- !.
icl_readable_solvable(solvable(Goal, Params, []), solvable(Goal, Params)) :- !.
icl_readable_solvable(solvable(Goal, Params, Perms),
solvable(Goal, Params, Perms)) :- !.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name: icl_minimally_instantiate_solvables(+ShorthandSolvables,
% -MinimalSolvables).
% purpose: Convert from shorthand (or standard form) to minimally instantiated
% solvables list.
% remarks: - This is special-purpose. It's used to massage a list of solvables
% that are to be UNdeclared, to make sure each of them will unify
% with some existing solvable. Perms and Params are completely
% ignored in the unification; only the Goal is relevant. So each
% minimally instantiated solvable is simply solvable(Goal, _, _).
% - Note that "shorthand" means "anything goes" - so shorthand
% solvables are a superset of standard solvables.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% icl_minimally_instantiate_solvables(+ShorthandSolvables,
% -Solvables).
icl_minimally_instantiate_solvables([], []).
icl_minimally_instantiate_solvables([Shorthand | RestSH],
[Minimal | RestMin]) :-
icl_minimally_instantiate_solvable(Shorthand, Minimal),
icl_minimally_instantiate_solvables(RestSH, RestMin).
% icl_minimally_instantiate_solvable(+Shorthand, -Minimal).
icl_minimally_instantiate_solvable(solvable((Goal :- _Test), Params, Perms),
Minimal) :-
!,
icl_minimally_instantiate_solvable(solvable(Goal, Params, Perms),
Minimal).
icl_minimally_instantiate_solvable(solvable((Goal :- _Test), Params),
Minimal) :-
!,
icl_minimally_instantiate_solvable(solvable(Goal, Params, []), Minimal).
icl_minimally_instantiate_solvable(solvable((Goal :- _Test)), Minimal) :-
!,
icl_minimally_instantiate_solvable(solvable(Goal, [], []), Minimal).
icl_minimally_instantiate_solvable((Goal :- _Test), Minimal) :-
!,
icl_minimally_instantiate_solvable(solvable(Goal, [], []), Minimal).
icl_minimally_instantiate_solvable(solvable(Goal, _Params, _Perms),
solvable(Goal, _, _)) :-
!.
icl_minimally_instantiate_solvable(solvable(Goal, _Params),
solvable(Goal, _, _)) :-
!.
icl_minimally_instantiate_solvable(solvable(Goal), solvable(Goal, _, _)) :- !.
icl_minimally_instantiate_solvable(Goal, solvable(Goal, _, _)) :- !.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name: oaa_goal_matches_solvables(+Goal, +Solvables, +Types,
% -RealGoal, -MatchedSolvable).
% purpose: Determine whether a call to Goal is handled by the agent with
% these Solvables.
% arguments:
% - Goal must be non-compound (basic) to match: no address, no params,
% no subgoals.
% - Solvables must be in standard form.
% - Types is a sublist of [procedure, data, trigger]. The type of the
% returned solvable must be in this list.
% - RealGoal is what should actually be called, after taking synonyms
% into account.
% - MatchedSolvable is the solvable record corresponding to RealGoal.
% remarks:
% - A solvable's params may contain a single test, but it can
% be compound:
% solvable(g(X), [test((X > 1,X < 10))], [...]).
% Tests should contain only prolog builtins.
% - Any solvable can be a synonym of another solvable (including a
% synonym of a synonym), but eventually there must be a non-synonym
% solvable. Synonyms must be used with care. If predicate A
% is synonymed to predicate B, there must be a solvable for clause B,
% for A to be usable.
% - When a predicate A is synonymed to predicate B, all other params
% and all permissions associated with A are ignored.
% - Uses would_unify (and \+ \+) so that any variables in the goal are
% not bound by the solvable, thereby unnecessarily constraining query
% I forget why: I think it was because we had some problems
% matching solutions coming back. However, this has an unusual
% side effect: if your solvable is t(6) and your query is t(X),
% the query arrives at the agent as t(X), not t(6), which might
% be unexpected. Look into this more someday...
% - However, when Goal is a synonym, variables in the synonym param DO
% get unified correctly.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
oaa_goal_matches_solvables(Goal, Solvables, Types, RealGoal, RealMatched) :-
oaa_built_in_solvables(BuiltIns),
append(BuiltIns, Solvables, AllSolvables),
oaa_goal_in_solvables(Goal, AllSolvables, Types, Matched),
Matched = solvable(_, Params, _),
% See if Goal is a synonym predicate
( icl_GetParamValue(synonym(Goal, SynGoal), Params) ->
oaa_goal_matches_solvables(SynGoal, Solvables, Types, RealGoal, RealMatched)
| otherwise ->
RealGoal = Goal,
RealMatched = Matched
),
!.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% name: oaa_goal_in_solvables(+Goal, +Solvables, +Types, -MatchedSolvable).
% purpose: Determine whether a call to Goal is handled by the agent with
% these Solvables.
% (Determine whether Goal appears in Solvables, with
% appropriate Params and Perms for it to be called.)
% If so, returns the relevant solvable declaration.
% arguments:
% - Goal must be non-compound (basic) to match: no address, no params,
% no subgoals.
% - Solvables must be in standard form.
% - Types is a sublist of [procedure, data, trigger]. The type of the
% returned solvable must be in this list.
% remarks:
% - Should not be called directly; only by oaa_goal_matches_solvables.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
oaa_goal_in_solvables(Goal, [solvable(G1,Params,Perms) | _Rest], _Types,
solvable(G1,Params,Perms)) :-
would_unify(Goal, G1),
icl_GetParamValue(synonym(Goal, _RealGoal), Params),
% TBD: OK, so it's a synonym, but shouldn't we check
% the permissions and type for the referenced
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -