Replies: 6 comments 20 replies
-
Would the following approach work in your case: :- protocol(p).
:- public(p/1).
:- end_protocol.
:- category(cat1,
implements(p)).
p(1).
:- end_category.
:- category(cat2,
implements(p)).
p(2).
:- end_category.
:- category(cat3,
implements(p)).
p(3).
:- end_category.
:- category(cat,
extends((cat1,cat2,cat3))).
:- alias(cat1, [p/1 as p1/1]).
:- alias(cat2, [p/1 as p2/1]).
:- alias(cat3, [p/1 as p3/1]).
p(X) :- ^^p1(X).
p(X) :- ^^p2(X).
p(X) :- ^^p3(X).
:- end_category.
:- object(obj,
imports(cat)).
p(0).
p(X) :- ^^p(X).
:- end_object. Assuming the code above is saved in a
|
Beta Was this translation helpful? Give feedback.
-
That may be possible using the term-expansion mechanism: https://logtalk.org/manuals/userman/expansion.html You could use to generate at compile time the |
Beta Was this translation helpful? Give feedback.
-
See the Handbook section on Reflection. Also the documentation of the |
Beta Was this translation helpful? Give feedback.
-
(Please let me know if continuing to post my findings is inappropriate here.) I think I may have found an approach that is not perfect, but has some benefits and is (arguably) less error-prone (though still a bit wordy). Firstly, I introduced the :- category(requirement_inference).
:- multifile(inferred_requirement/1).
:- public(inferred_requirement/1).
:- public(requirement/1).
requirement(R) :- ::requires(R).
requirement(R) :- inferred_requirement(R).
:- public(includes_category/2).
includes_category(Entity, Category) :-
imports_category(Entity, Category).
includes_category(Entity, Category) :-
imports_category(Entity, Category1),
includes_category(Category1, Category).
includes_category(Category1, Category) :-
extends_category(Category1, Category).
includes_category(Category1, Category) :-
extends_category(Category1, Category2),
includes_category(Category2, Category).
:- end_category. At its core, it relies on :- category(c_compiler_requirement_inference, extends(requirement_inference)).
:- multifile(requirement_inference::inferred_requirement/1).
requirement_inference::inferred_requirement(c_compiler(_)) :-
self(Self),
Self::includes_category(Self, c_compiler_requirement_inference),
c_files_present(Self). % fake implementation here for brevity
:- end_category. It's not as succinct as I would like it to be because of
But it's not too bad, I suppose. And it doesn't require term expansion. Now, returning to
This concept also defines the I am also not sure my implementation of |
Beta Was this translation helpful? Give feedback.
-
Thinking that the "many worlds" design pattern may be a good fit here, with a package being a world. See e.g. https://logtalk.org/2019/11/13/many-worlds-design-pattern.html See also the |
Beta Was this translation helpful? Give feedback.
-
It's not clear to me why a package need to import anything. Maybe I'm stuck in the view of packages as essentially declarative manifests, possibly implementing different protocols (with likely some common minimal protocol). It would be the details of the package manifest that would result in different sets of inferences being applied. Composable inferences would still apply but the packages would work as blueprints directing requirements satisfaction to different objects importing different sets of categories, with each category implementing some cohesive subset of rules. |
Beta Was this translation helpful? Give feedback.
-
I have a case where I am trying to use categories to supplement predicate clauses.
Let's say we have an object
obj
that importspreds
category which implementspred/0
. Callingobj::pred
will work fine. Then, if we want to add clauses to it inobj
, simply definingpred/0
will overridepreds
's version ofpred/0
and we need to explicitly fall back onto it by adding a clausepred :- ^^pred
. Not pretty, but ok.However, It gets really hairy if
preds
is a category that extends multiple categories providing their clauses forpred/0
. Using^^
won't work as it won't call all clauses but only ones found first when going through the list of extended categories.Ultimately, I am trying to use categories to mix in different clauses but it seems that either they are not fit for purpose or I need to reconsider my approach altogether.
Any suggestions on how to best achieve this?
Beta Was this translation helpful? Give feedback.
All reactions