diff --git a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java index 51bd36f3..b8be840c 100644 --- a/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java +++ b/klab.services.resolver/src/main/java/org/integratedmodelling/klab/services/resolver/DataflowCompiler.java @@ -3,17 +3,12 @@ import org.integratedmodelling.common.runtime.ActuatorImpl; import org.integratedmodelling.common.runtime.DataflowImpl; import org.integratedmodelling.common.utils.Utils; -import org.integratedmodelling.klab.api.collections.Pair; -import org.integratedmodelling.klab.api.collections.Triple; -import org.integratedmodelling.klab.api.geometry.Geometry; import org.integratedmodelling.klab.api.knowledge.Model; import org.integratedmodelling.klab.api.knowledge.Observable; import org.integratedmodelling.klab.api.knowledge.ObservationStrategy; import org.integratedmodelling.klab.api.knowledge.Resolvable; import org.integratedmodelling.klab.api.knowledge.observation.Observation; import org.integratedmodelling.klab.api.knowledge.observation.scale.Scale; -import org.integratedmodelling.klab.api.lang.Contextualizable; -import org.integratedmodelling.klab.api.lang.ServiceCall; import org.integratedmodelling.klab.api.scope.ContextScope; import org.integratedmodelling.klab.api.services.resolver.Coverage; import org.integratedmodelling.klab.api.services.runtime.Actuator; @@ -48,7 +43,72 @@ Set it into dataflow (if null, set, else intersect) return ret; } - private List compileActuator(Resolvable resolvable, ResolutionGraph resolutionGraph, Coverage geometry, Observation observation, String strategyUrn, Map catalog) { + /** + * The entry point is calling this with a null strategy for all root observation nodes. Otherwise locate + * and contextualize the entry point and call one of the others on the correspondent actuator. + * + * @param observation + * @param strategy + * @return + */ + + Actuator compileObservation(Observation observation, ObservationStrategy strategy) { + + // a. scan children: + // i. coverage is in the edge linking to the strategy + // ii. resolvable is strategy (must be for observation) + // iii. when strategy exists and isn't empty, make actuator with obs ID and Observable + // iv. pass it to compileStrategy(actuator, obs, scale, strategy) + + + return null; + } + + Actuator compileStrategy(Actuator observationActuator, Observation observation, Scale scale, + ObservationStrategy observationStrategy) { + + // children: model (the plan for the resolution) or Strategy (deferred) + // if model + // determine model coverage, intersect if needed + // pass to compileModel(actuator, obs, scale, strategy, model) + // if strategy + // compile into actuator for deferring at point of resolution (in computations) + // + + return null; + } + + Actuator compileModel(Actuator observationActuator, Observation observation, Scale scale, + ObservationStrategy observationStrategy, Model model) { + + // compileModel(actuator, obs, scale, strategy, model) + // finds Observation: call compileObservation(obs, strategy), + // add all computations and any deferrals + + return null; + } + + // (OBS) (O) earth:Region [#-1] + // (S) urn='substantial.direct', operations=[OBSERVE (O) earth:Region] + // (M) staging.vxii.basic.region-resolver + // (OBS) (O) geography:Elevation [#61920] + // (S) urn='dependent.direct', operations=[OBSERVE (O) geography:Elevation] + // (M) staging.vxii.basic.elevation-resolver + // (OBS) (O) geography:Slope [#61920] + // (S) urn='dependent.direct', operations=[OBSERVE (O) geography:Slope] + // (M) staging.vxii.basic.slope-resolver + // + // + // 1. call compileObservation(obs, strategy = null) + // + // compileStrategy(actuator, obs, scale, strategy) + // + // + // each Compile returns ONE actuator and adds those from the children + + private List compileActuator(Resolvable resolvable, ResolutionGraph resolutionGraph, + Coverage geometry, Observation observation, String strategyUrn, + Map catalog) { List ret = new ArrayList<>(); if (resolvable instanceof ObservationStrategy observationStrategy) { @@ -57,11 +117,13 @@ private List compileActuator(Resolvable resolvable, ResolutionGraph re } for (var edge : resolutionGraph.graph().incomingEdgesOf(resolvable)) { - ret.addAll(compileActuator(resolutionGraph.graph().getEdgeSource(edge), resolutionGraph, geometry, observation, observationStrategy.getUrn(), catalog)); + ret.addAll(compileActuator(resolutionGraph.graph().getEdgeSource(edge), resolutionGraph, + geometry, observation, observationStrategy.getUrn(), catalog)); } } else if (resolvable instanceof Observation obs) { for (var edge : resolutionGraph.graph().incomingEdgesOf(resolvable)) { - ret.addAll(compileActuator(resolutionGraph.graph().getEdgeSource(edge), resolutionGraph, Coverage.create(Scale.create(obs.getGeometry()), 1.0), obs, strategyUrn, catalog)); + ret.addAll(compileActuator(resolutionGraph.graph().getEdgeSource(edge), resolutionGraph, + Coverage.create(Scale.create(obs.getGeometry()), 1.0), obs, strategyUrn, catalog)); } } else if (resolvable instanceof Model model) { /* @@ -77,120 +139,123 @@ private List compileActuator(Resolvable resolvable, ResolutionGraph re } - // public Dataflow compile(Resolvable knowledge, Resolution resolution, ContextScope scope) { -// -// DataflowImpl ret = new DataflowImpl(); -// Actuator rootActuator = null; -// Map compiled = new HashMap<>(); -// -// for (Pair root : resolution.getResolution()) { -// -// if (root.getFirst() instanceof Model) { -// var actuator = compileActuator((Model) root.getFirst(), resolution, root.getSecond(), -// resolution.getResolvable(), -// null, -// ret, compiled, scope); -// if (rootActuator == null) { -// ret.getComputation().add(actuator); -// } else { -// rootActuator.getChildren().add(actuator); -// } -// } -// } -// -// ret.computeCoverage(); -// -// return ret; -// } -// -// private ActuatorImpl compileActuator(Model model, Resolution resolution, Coverage coverage, -// Resolvable resolvable, -// Actuator parentActuator, Dataflow dataflow, -// Map compiled, ContextScope scope) { -// -// if (resolvable instanceof Observable observable) { -// -// ActuatorImpl ret = null; -// var id = createId(observable, scope); -// -// if (compiled.containsKey(observable.getReferenceName())) { -// ret = compileReference(compiled.get(observable.getReferenceName())); -// } else { -// -// ret = new ActuatorImpl(); -// -// // keep the coverage in the dataflow aux data if it's not full, so that the runtime doesn't -// // have to -// // recalculate it. -// if (coverage.getCoverage() < 1) { -// dataflow.getResources().put(id + "_coverage", coverage); -// } -// -// // dependencies first -// for (ResolutionType type : new ResolutionType[]{ResolutionType.DIRECT, -// ResolutionType.DEFER_INHERENCY, -// ResolutionType.DEFER_SEMANTICS}) { -// for (Triple resolved : resolution.getResolving( -// model, -// type)) { -// // alias is the dependency getName() -// if (resolved.getFirst() instanceof Model m) { -// var dependency = compileActuator(m, resolution, resolved.getThird(), -// resolved.getSecond(), ret, dataflow, -// compiled, scope); -// ret.getChildren().add(dependency); -// ret.setCoverage(((Model) resolved.getFirst()).getCoverage().as(Geometry.class)); -// } else if (resolved.getFirst() instanceof Observable o) { -// // ret.getDeferrals().add(Pair.of(type, o)); -// } -// } -// } -// } -// -// // self -// for (Contextualizable computation : model.getComputation()) { -// -// /* -// * TODO establish which components are needed to satisfy the call, and make the -// * dataflow empty if the resource services in the scope do not locate a component. -// * (shouldn't happen as the models shouldn't be resolved in that case). Versions -// * should also be collected. -// */ -// -// ret.getComputation().add(getServiceCall(computation)); -// } -// -// // GAAAH -// // ret.setId(id); -// ret.setName(observable.getName()); -// ret.setAlias(observable.getStatedName()); -// -// // add to hash -// compiled.put(observable.getReferenceName(), ret); -// -// // filters apply to references as well -// for (Triple resolved : resolution.getResolving( -// model, -// ResolutionType.FILTER)) { -// // TODO -// } -// -// ret.setObservable(observable); -// ret.setAlias(observable.getName()); -// -// return ret; -// } -// -// // TODO -// return null; -// } -// -// private ServiceCall getServiceCall(Contextualizable computation) { -// if (computation.getServiceCall() != null) { -// return computation.getServiceCall(); -// } -// return null; -// } + // public Dataflow compile(Resolvable knowledge, Resolution resolution, ContextScope + // scope) { + // + // DataflowImpl ret = new DataflowImpl(); + // Actuator rootActuator = null; + // Map compiled = new HashMap<>(); + // + // for (Pair root : resolution.getResolution()) { + // + // if (root.getFirst() instanceof Model) { + // var actuator = compileActuator((Model) root.getFirst(), resolution, root.getSecond(), + // resolution.getResolvable(), + // null, + // ret, compiled, scope); + // if (rootActuator == null) { + // ret.getComputation().add(actuator); + // } else { + // rootActuator.getChildren().add(actuator); + // } + // } + // } + // + // ret.computeCoverage(); + // + // return ret; + // } + // + // private ActuatorImpl compileActuator(Model model, Resolution resolution, Coverage coverage, + // Resolvable resolvable, + // Actuator parentActuator, Dataflow dataflow, + // Map compiled, ContextScope scope) { + // + // if (resolvable instanceof Observable observable) { + // + // ActuatorImpl ret = null; + // var id = createId(observable, scope); + // + // if (compiled.containsKey(observable.getReferenceName())) { + // ret = compileReference(compiled.get(observable.getReferenceName())); + // } else { + // + // ret = new ActuatorImpl(); + // + // // keep the coverage in the dataflow aux data if it's not full, so that the runtime + // doesn't + // // have to + // // recalculate it. + // if (coverage.getCoverage() < 1) { + // dataflow.getResources().put(id + "_coverage", coverage); + // } + // + // // dependencies first + // for (ResolutionType type : new ResolutionType[]{ResolutionType.DIRECT, + // ResolutionType.DEFER_INHERENCY, + // ResolutionType.DEFER_SEMANTICS}) { + // for (Triple resolved : resolution.getResolving( + // model, + // type)) { + // // alias is the dependency getName() + // if (resolved.getFirst() instanceof Model m) { + // var dependency = compileActuator(m, resolution, resolved.getThird(), + // resolved.getSecond(), ret, dataflow, + // compiled, scope); + // ret.getChildren().add(dependency); + // ret.setCoverage(((Model) resolved.getFirst()).getCoverage().as(Geometry + // .class)); + // } else if (resolved.getFirst() instanceof Observable o) { + // // ret.getDeferrals().add(Pair.of(type, o)); + // } + // } + // } + // } + // + // // self + // for (Contextualizable computation : model.getComputation()) { + // + // /* + // * TODO establish which components are needed to satisfy the call, and make the + // * dataflow empty if the resource services in the scope do not locate a component. + // * (shouldn't happen as the models shouldn't be resolved in that case). Versions + // * should also be collected. + // */ + // + // ret.getComputation().add(getServiceCall(computation)); + // } + // + // // GAAAH + // // ret.setId(id); + // ret.setName(observable.getName()); + // ret.setAlias(observable.getStatedName()); + // + // // add to hash + // compiled.put(observable.getReferenceName(), ret); + // + // // filters apply to references as well + // for (Triple resolved : resolution.getResolving( + // model, + // ResolutionType.FILTER)) { + // // TODO + // } + // + // ret.setObservable(observable); + // ret.setAlias(observable.getName()); + // + // return ret; + // } + // + // // TODO + // return null; + // } + // + // private ServiceCall getServiceCall(Contextualizable computation) { + // if (computation.getServiceCall() != null) { + // return computation.getServiceCall(); + // } + // return null; + // } /* * The actuator ID is also the observation ID when the actuator runs. It reflects the context @@ -207,7 +272,7 @@ private String createId(Observable observable, ContextScope scope) { return (scope.getContextObservation() == null ? "" : (scope.getContextObservation().getId() + ".")) + observable.getDescriptionType().name().toLowerCase() + "." + observable.getReferenceName() + "." + (observable.getObserver() == null ? scope.getIdentity().getId() : - ("_as_" + observable.getObserver().codeName())); + ("_as_" + observable.getObserver().codeName())); } /**