Multiple variants of types for GP functions and terminals

29 views
Skip to first unread message

RomanT

unread,
May 9, 2025, 6:05:21 PMMay 9
to deap-users
Hi,

Presently, it's possible to assign single type to GP terminal and single combination of [(input_types) -> output_type] to GP function.

Is it possible for a terminal to have multiple possible return types, and for a function to have multiple possible  [(input_types) -> output_type] combinations?

Thank you.

Daniel

unread,
May 10, 2025, 6:52:58 AMMay 10
to deap-...@googlegroups.com

It looks like what you're looking for is the original Generic described by D. Montana in his paper on STGP.

DEAP has no direct support for Generics but it is doable, although the effort is significant: overriding PrimitimiveSetTyped, genFull, genGrow, and genHalfAndHalf.

Terminal itself can't have multiple return types. Terminal is a concrete value conceptually, I haven't seen any system capable of representing the same terminal with multiple types, although, if type inheritance is introduced the terminal may be used for a subset of types.

The simple approach with DEAP ould be to add the same terminal with the different type to the PrimitiveSetTyped.

--
You received this message because you are subscribed to the Google Groups "deap-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to deap-users+...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/deap-users/0b55bb54-60e9-4ad7-99e5-d819a9aa041bn%40googlegroups.com.
-- 
Regards, Daniel.

EBo

unread,
May 10, 2025, 7:03:43 AMMay 10
to deap-...@googlegroups.com, Daniel
I would add, that if you end up getting a full generic implemented,
there are a few people here that would like to hear about it.
>> <https://groups.google.com/d/msgid/deap-users/0b55bb54-60e9-4ad7-99e5-d819a9aa041bn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>
> --
> Regards, Daniel.

RomanT

unread,
May 10, 2025, 7:23:25 AMMay 10
to deap-users
Daniel,

Understood, thank you. That's what I presumed, but anyway it was worth asking.

Will look into it... generics might be an overkill for my case, but functions that are capable of accepting multiple combinations of input types with respective output types are definitely of need.

Daniel

unread,
May 10, 2025, 7:28:26 AMMay 10
to deap-...@googlegroups.com

Out of curiosity: what's your domain and the use case?

When I've been in need for generics, I've managed to workaround in a case-specific way. My case was related to having both scalars (bool, int, float) and series of those values. I've ended up bridging the scalar and series unilaterally: a last_bool(series_bool) -> bool, last_int(series_int) -> int, ... were introduced. It had some clarity impact obviously (last_* was everywhere) but that was easy to edit later.

RomanT

unread,
May 10, 2025, 8:39:10 AMMay 10
to deap-users
That's a sort of an engineering task, data is represented by vectors of floats and scalars, operations between vectors are possible, as well as between scalars and mixed (vectors and scalars). Dome operations might alter the types of the inputs: two vectors of similar type, after a particular function is applied to them, would give another type as an output. So it's pretty big set of types that are to be managed carefully. One type combination per function is not enough.

RomanT

unread,
May 10, 2025, 8:40:03 AMMay 10
to deap-users
* Dome = Some. Typo.

Daniel

unread,
May 10, 2025, 9:03:08 AMMay 10
to deap-...@googlegroups.com

I see. Well, you will have to be very creative with your primitive set and types hierarchy when implementing this  in the scope of DEAP. I'm not sure if generics will be enough.

Because of the limited support of STGP in DEAP, you can try to go the other way around. Something in your whole system must perform the type inference and control the generation. Given the DEAP limitations, you can drop its typing completely, come up with a custom tree generator, rewrite the genFull, Grow, HalfAndHalf, and use PrimitiveSet (not typed). Then either introduce a tree repair functionality that will try to make a valid tree from an invalid one (default genetic operators will still do bad things with your trees) OR make your primitives somehow resolve the issue at their level (think what protected division does and come up with a similar solution for your primitives).

This is a pretty complex task. Given what you're doing, I would suggest to take a look at the Grammatical Evolution[1] and its particular implementation, e.g. PonyGE2[2]. It allows you to define what's called "an arbitrary language" where you will define the resulting program in a form of a BNF which is much more flexible than types.

It has its pros and cons, the performance and extensibility of this thing though... You should allocate quite some time to this project.

[1] https://en.wikipedia.org/wiki/Grammatical_evolution
[2] https://github.com/PonyGE/PonyGE2

RomanT

unread,
May 10, 2025, 9:37:51 AMMay 10
to deap-users
Yep, I'm assessing the variants...

Thank you for your suggestions and for the link to PonyGE! I'm not STGP-addicted, any means that would help me resolve the task would be fine, but STCG is the best alternative so far.

Will look into grammatical evolution as well.
Reply all
Reply to author
Forward
0 new messages