Skip to content

Commit

Permalink
WIP: Implement receptor effector base class
Browse files Browse the repository at this point in the history
- replace 'parameterized' with 'parametric' everywhere
- no functional or interface changes

Signed-off-by: jrte <jrte.project@gmail.com>
  • Loading branch information
jrte committed Jun 19, 2024
1 parent 620e67d commit e0e14cc
Show file tree
Hide file tree
Showing 19 changed files with 115 additions and 112 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ In a nutshell, _algorithms_ are congruent to _patterns_. The _logic_ is in the _
## Basic Concepts
Ginr operates in a symbolic domain involving a finite set of symbols and algebraic semiring operators that recombine symbols to express syntactic patterns. Support for Unicode symbols and binary data is built in, and Unicode in ginr source patterns is rendered as UTF-8 byte sequences in compiled automata. UTF-8 text is transduced without decoding and extracted bytes are decoded only in target effectors. Ribose transducer patterns may introduce additional atomic symbols as tokens representing out-of-band (>255) control signals.

Input patterns are expressed in `{byte,signal}*` semirings, and may involve UTF-8 and binary bytes from an external source as well as control signals interjected by target effectors. Ribose transducer patterns are expressed in `(input,effector,parameter)*` semirings, mapping input patterns onto parameterized effectors expressed by domain-specific target classes. They identify syntactic features of interest in the input and apply target effectors to extract and assimilate features into the target domain.
Input patterns are expressed in `{byte,signal}*` semirings, and may involve UTF-8 and binary bytes from an external source as well as control signals interjected by target effectors. Ribose transducer patterns are expressed in `(input,effector,parameter)*` semirings, mapping input patterns onto parametric effectors expressed by domain-specific target classes. They identify syntactic features of interest in the input and apply target effectors to extract and assimilate features into the target domain.

A ribose model is associated with a target class and is a container for related collections of transducers, target effectors, static effector parameters, control signals and field registers for accumulating extracted bytes. The `ITransductor` implementation that governs ribose transductions provides a base set of effectors to
- extract and compose data in selected fields *(`select, paste, copy, cut, clear`)*,
Expand All @@ -85,7 +85,7 @@ A ribose model is associated with a target class and is a container for related

All ribose models implicitly inherit the transductor effectors, along with an extensible set of control signals `{nul,nil,eol,eos}` and an anonymous field that is preselected for every transduction and reselected when `select` is invoked with no parameter. New signals and fields referenced in transducer patterns implicitly extend the base signal and field collections. Additional effectors may be defined in specialized `ITarget` implementation classes.

The ribose transductor implements `ITarget` and its effectors are sufficient for most ribose models that transduce input to standard output via the `out[...]` effector. Domain-specific target classes may extend `SimpleTarget` to express additional effectors, typically as inner classes specializing `BaseEffector<Target>` or `BaseParameterizedEffector<Target,ParameterType>`. All effectors are provided with a reference to the containing target instance and an `IOutput` view for extracting fields as `byte[]`, integer, floating point or Unicode `char[]` values, typically for inclusion in immutable value objects that are incorporated into the target model.
The ribose transductor implements `ITarget` and its effectors are sufficient for most ribose models that transduce input to standard output via the `out[...]` effector. Domain-specific target classes may extend `SimpleTarget` to express additional effectors, typically as inner classes specializing `BaseEffector<Target>` or `BaseParametricEffector<Target,ParameterType>`. All effectors are provided with a reference to the containing target instance and an `IOutput` view for extracting fields as `byte[]`, integer, floating point or Unicode `char[]` values, typically for inclusion in immutable value objects that are incorporated into the target model.

Targets need not be monolithic. In fact, every ribose transduction involves a composite target comprised of the transductor and at least one other target class (e.g., `SimpleTarget`). In a composite target one target class is selected as the representative target, which instantiates and gathers effectors from subordinate targets to merge with its own effectors into a single collection to merge with the transductor effectors. Composite targets allow separable concerns within complex semantic domains to be encapsulated in discrete interoperable and reusable targets. For example, a validation model containing a collection of transducers that syntactically recognize domain artifacts would be bound to a target expressing effectors to support semantic validation. The validation model and target, supplied by the service vendor, can then be combined with specialized models in receiving domains to obtain a composite model including validation and reception models and effectors. With some ginr magic receptor patterns can be joined with corresponding validator patterns to obtain receptors that validate in stepwise synchrony with reception and assimilation into the receiving domain.
### Use Cases
Expand Down
14 changes: 7 additions & 7 deletions overview.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<br><br>
Ginr automata for ribose are 3-tape finite state transducers (FSTs) compiled
from 3-dimensional regular patterns that express the source syntax on the input tape and
unambiguously map it onto parameterized effectors, expressed by a target, that extract and
unambiguously map it onto parametric effectors, expressed by a target, that extract and
assimilate input data into the target domain. Ginr encodes Unicode literal characters and
tokens, eg 'Σ', 'Π', `ΣΠ`, as multibyte UTF-8 sequences and the encoded form is used
throughout ribose. This is largely transparent to end users, but care must be taken when
Expand Down Expand Up @@ -131,16 +131,16 @@
reference to the target instance and an {@code IOutput} instance that supports
conversion of transducer fields to Java primitive values or {@code byte[]} or
{@code char[]} arrays. There are three types of effectors: simple effector,
parameterized effector and receptor effector. Simple effectors extend {@code
parametric effector and receptor effector. Simple effectors extend {@code
IEffector<T extends ITarget>}, which expresses a niladic {@code invoke()} method
that is called when the effector fires in running transduction. Parameterized
effectors extend {@code IParameterizedEffector<T extends ITarget, P> extends
that is called when the effector fires in running transduction. Parametric
effectors extend {@code IParametricEffector<T extends ITarget, P> extends
IEffector<T>>} and contain an array {@code P[]} of parametric objects compiled
from lists effector tokens. Parameterized effectors inherit {@code IEffector.invoke()}
from lists effector tokens. Parametric effectors inherit {@code IEffector.invoke()}
and add a monadic {@code invoke(int)} method, where the {@code int} argument selects
a specific {@code P} instance to use. Receptor effectors are specialized parameterized
a specific {@code P} instance to use. Receptor effectors are specialized parametric
effectors that extend {@code BaseReceptorEffector<T extends ITarget> extends
BaseParameterizedEffector<T, Receiver[]>}. Receptor effectors express public fields
BaseParametricEffector<T, Receiver[]>}. Receptor effectors express public fields
that receive data decoded from transducer fields.
<br><br>
The transductor is itself a target expressing a suite of core effectors that are
Expand Down
10 changes: 5 additions & 5 deletions src/com/characterforming/jrte/engine/BaseFieldEffector.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@
import java.nio.charset.CharacterCodingException;

import com.characterforming.ribose.IToken;
import com.characterforming.ribose.base.BaseParameterizedEffector;
import com.characterforming.ribose.base.BaseParametricEffector;
import com.characterforming.ribose.base.TargetBindingException;

/**
* Base class for parameterized field effectors, which are invoked with
* Base class for parametric field effectors, which are invoked with
* field name parameters. The setParamater(int, charset, byte[][]), invoke(), and
* invoke(int) methods must be implemented by subclasses.
*
* @author Kim Briggs
*/
abstract class BaseFieldEffector extends BaseParameterizedEffector<Transductor, Integer> {
abstract class BaseFieldEffector extends BaseParametricEffector<Transductor, Integer> {
/**
* Constructor
*
Expand All @@ -45,12 +45,12 @@ protected BaseFieldEffector(final Transductor transductor, final String name) th
super(transductor, name);
}

@Override // @see com.characterforming.ribose.IParameterizedEffector#allocateParameters(int)
@Override // @see com.characterforming.ribose.IParametricEffector#allocateParameters(int)
public Integer[] allocateParameters(int parameterCount) {
return new Integer[parameterCount];
}

@Override // IParameterizedEffector#compileParameter(IToken[])
@Override // IParametricEffector#compileParameter(IToken[])
public Integer compileParameter(final IToken[] parameterList) throws TargetBindingException {
if (parameterList.length != 1) {
throw new TargetBindingException(String.format("%1$s.%2$s[]: effector accepts exactly one parameter",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
import java.nio.charset.CharacterCodingException;

import com.characterforming.ribose.IToken;
import com.characterforming.ribose.base.BaseParameterizedEffector;
import com.characterforming.ribose.base.BaseParametricEffector;
import com.characterforming.ribose.base.EffectorException;
import com.characterforming.ribose.base.TargetBindingException;

/**
* @author Kim Briggs
*/
abstract class BaseInputOutputEffector extends BaseParameterizedEffector<Transductor, IToken[]> {
abstract class BaseInputOutputEffector extends BaseParametricEffector<Transductor, IToken[]> {
/**
* Constructor
*
Expand All @@ -42,17 +42,17 @@ protected BaseInputOutputEffector(Transductor transductor, String name) throws C
super(transductor, name);
}

@Override // @see com.characterforming.ribose.IParameterizedEffector#invoke()
@Override // @see com.characterforming.ribose.IParametricEffector#invoke()
public int invoke() throws EffectorException {
throw new EffectorException(String.format("The %1$s effector requires at least one parameter", super.getName()));
}

@Override // @see com.characterforming.ribose.IParameterizedEffector#allocateParameters(int)
@Override // @see com.characterforming.ribose.IParametricEffector#allocateParameters(int)
public IToken[][] allocateParameters(int parameterCount) {
return new IToken[parameterCount][];
}

@Override // @see com.characterforming.ribose.IParameterizedEffector#compileParameter(IToken[])
@Override // @see com.characterforming.ribose.IParametricEffector#compileParameter(IToken[])
public IToken[] compileParameter(final IToken[] parameterList) throws TargetBindingException {
if (parameterList.length < 1) {
throw new TargetBindingException(String.format(
Expand Down
2 changes: 1 addition & 1 deletion src/com/characterforming/jrte/engine/Chain.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ boolean isEffector() {
&& this.effectVector[1] == 0;
}

boolean isParameterizedEffector() {
boolean isParametricEffector() {
return this.effectVector.length == 3
&& this.effectVector[0] < 0
&& this.effectVector[2] == 0;
Expand Down
16 changes: 8 additions & 8 deletions src/com/characterforming/jrte/engine/Model.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@
import java.util.logging.Logger;

import com.characterforming.ribose.IEffector;
import com.characterforming.ribose.IParameterizedEffector;
import com.characterforming.ribose.IParametricEffector;
import com.characterforming.ribose.ITarget;
import com.characterforming.ribose.IToken;
import com.characterforming.ribose.ITransduction;
import com.characterforming.ribose.ITransductor;
import com.characterforming.ribose.base.BaseEffector;
import com.characterforming.ribose.base.BaseParameterizedEffector;
import com.characterforming.ribose.base.BaseParametricEffector;
import com.characterforming.ribose.base.Bytes;
import com.characterforming.ribose.base.Codec;
import com.characterforming.ribose.base.CompilationException;
Expand Down Expand Up @@ -256,7 +256,7 @@ protected boolean save(Argument[][] effectorParameters) {
for (int effectorOrdinal = 0; effectorOrdinal < this.effectorOrdinalMap.size(); effectorOrdinal++) {
Argument[] arguments = effectorParameters[effectorOrdinal];
if (arguments != null && arguments.length > 0) {
assert this.proxyEffectors[effectorOrdinal] instanceof IParameterizedEffector<?, ?>;
assert this.proxyEffectors[effectorOrdinal] instanceof IParametricEffector<?, ?>;
this.writeArguments(arguments);
} else
this.writeInt(-1);
Expand Down Expand Up @@ -324,7 +324,7 @@ protected Model load() throws ModelException, CharacterCodingException {
IToken[][] parameterTokens = new IToken[effectorArguments.length][];
for (int i = 0; i < effectorArguments.length; i++)
parameterTokens[i] = Token.getParameterTokens(this, effectorArguments[i]);
if (this.proxyEffectors[effectorOrdinal] instanceof BaseParameterizedEffector<?, ?> effector)
if (this.proxyEffectors[effectorOrdinal] instanceof BaseParametricEffector<?, ?> effector)
effector.compileParameters(parameterTokens, errors);
if (this.targetMode.isLive())
this.proxyEffectors[effectorOrdinal].passivate();
Expand Down Expand Up @@ -387,7 +387,7 @@ public boolean map(PrintStream mapWriter) {
for (int effector = 0; effector < effectorIndex.length; effector++) {
mapWriter.printf("%1$6d effector %2$s", effector,
effectorIndex[effector].asString());
if (this.proxyEffectors[effector] instanceof BaseParameterizedEffector<?, ?> proxyEffector) {
if (this.proxyEffectors[effector] instanceof BaseParametricEffector<?, ?> proxyEffector) {
mapWriter.printf(" [ %1$s ]%n", proxyEffector.showParameterType());
for (int parameter = 0; parameter < proxyEffector.getParameterCount(); parameter++)
mapWriter.printf("%1$6d parameter %2$s%n", parameter, proxyEffector.showParameterTokens(parameter));
Expand Down Expand Up @@ -435,18 +435,18 @@ protected Argument[][] compileModelParameters(List<String> errors) throws Effect
for (int effectorOrdinal = 0; effectorOrdinal < this.proxyEffectors.length; effectorOrdinal++) {
HashMap<Argument, Integer> parametersMap = this.effectorParametersMaps.get(effectorOrdinal);
this.proxyEffectors[effectorOrdinal].setOutput(this.proxyTransductor);
if (this.proxyEffectors[effectorOrdinal] instanceof BaseParameterizedEffector<?,?> parameterizedEffector) {
if (this.proxyEffectors[effectorOrdinal] instanceof BaseParametricEffector<?,?> parametricEffector) {
if (parametersMap != null) {
assert parametersMap != null: String.format("Effector parameters map is null for %1$s effector",
parameterizedEffector.getName());
parametricEffector.getName());
Argument[] arguments = new Argument[parametersMap.size()];
IToken[][] tokens = new IToken[arguments.length][];
for (Map.Entry<Argument, Integer> e : parametersMap.entrySet()) {
int ordinal = e.getValue(); Argument argument = e.getKey();
tokens[ordinal] = Token.getParameterTokens(this, argument);
arguments[ordinal] = argument;
}
parameterizedEffector.compileParameters(tokens, errors);
parametricEffector.compileParameters(tokens, errors);
effectorArguments[effectorOrdinal] = arguments;
} else
effectorArguments[effectorOrdinal] = new Argument[0];
Expand Down
2 changes: 1 addition & 1 deletion src/com/characterforming/jrte/engine/ModelCompiler.java
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ void putAutomaton() throws CharacterCodingException {
transitionMatrix[inputOrdinal][rteState][1] = 1;
else if (chain.isEffector())
transitionMatrix[inputOrdinal][rteState][1] = effectVector[0];
else if (chain.isParameterizedEffector())
else if (chain.isParametricEffector())
transitionMatrix[inputOrdinal][rteState][1] = Transducer.action(-1 * effectVector[0], effectVector[1]);
else
transitionMatrix[inputOrdinal][rteState][1] = -1 * this.effectorVectorMap.computeIfAbsent(
Expand Down
14 changes: 7 additions & 7 deletions src/com/characterforming/jrte/engine/ModelLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
import java.util.logging.Level;

import com.characterforming.ribose.IEffector;
import com.characterforming.ribose.IParameterizedEffector;
import com.characterforming.ribose.IParametricEffector;
import com.characterforming.ribose.IModel;
import com.characterforming.ribose.ITarget;
import com.characterforming.ribose.ITransduction;
import com.characterforming.ribose.ITransductor;
import com.characterforming.ribose.ITransductor.Metrics;
import com.characterforming.ribose.base.BaseParameterizedEffector;
import com.characterforming.ribose.base.BaseParametricEffector;
import com.characterforming.ribose.base.Bytes;
import com.characterforming.ribose.base.Codec;
import com.characterforming.ribose.base.DomainErrorException;
Expand Down Expand Up @@ -104,12 +104,12 @@ public ITransductor transductor(ITarget target)
} catch (EffectorException e) {
throw new ModelException(e);
}
if (super.proxyEffectors[i] instanceof IParameterizedEffector<?, ?> proxyEffector) {
if (boundFx[i] instanceof BaseParameterizedEffector<?, ?> boundEffector)
if (super.proxyEffectors[i] instanceof IParametricEffector<?, ?> proxyEffector) {
if (boundFx[i] instanceof BaseParametricEffector<?, ?> boundEffector)
boundEffector.setParameters(proxyEffector);
else
throw new ModelException(String.format(
"Target effector '%s' implementation must extend BaseParameterizedEffector<?, ?>", proxyEffector.getClass().getName()));
"Target effector '%s' implementation must extend BaseParametricEffector<?, ?>", proxyEffector.getClass().getName()));
}
}
trex.setEffectors(boundFx);
Expand Down Expand Up @@ -267,7 +267,7 @@ public void decompile(final String transducerName)
System.out.printf("%1$d %2$d -> %3$d", from, equivalent, to);
if (effect >= 0x10000) {
int effectorOrdinal = Transducer.effector(effect);
if (super.proxyEffectors[effectorOrdinal] instanceof BaseParameterizedEffector<?, ?> effector) {
if (super.proxyEffectors[effectorOrdinal] instanceof BaseParametricEffector<?, ?> effector) {
int parameterOrdinal = Transducer.parameter(effect);
System.out.printf(" %s[", effectorNames[effectorOrdinal]);
System.out.printf(" %s ]", effector.showParameterTokens(parameterOrdinal));
Expand All @@ -282,7 +282,7 @@ public void decompile(final String transducerName)
System.out.printf(" %s", effectorNames[effectorVectors[index++]]);
else {
int effectorOrdinal = -1 * effectorVectors[index++];
if (super.proxyEffectors[effectorOrdinal] instanceof BaseParameterizedEffector<?,?> effector) {
if (super.proxyEffectors[effectorOrdinal] instanceof BaseParametricEffector<?,?> effector) {
int parameterOrdinal = Transducer.parameter(effectorVectors[index++]);
System.out.printf(" %s[", effectorNames[effectorOrdinal]);
System.out.printf(" %s ]", effector.showParameterTokens(parameterOrdinal));
Expand Down
Loading

0 comments on commit e0e14cc

Please sign in to comment.