268 lines
7.5 KiB
TypeScript
268 lines
7.5 KiB
TypeScript
/**
|
|
* @author Martin Karkowski
|
|
* @email m.karkowski@zema.de
|
|
* @create date 2020-02-20 19:42:06
|
|
* @modify date 2020-07-18 08:12:49
|
|
* @desc [description]
|
|
*/
|
|
|
|
import * as handlebars from "handlebars";
|
|
import { updateIds } from "../../ZISS-Network/helpers/idUpdater";
|
|
import { ILogicNetwork } from "../../ZISS-Network/type/ILogicNetwork";
|
|
import { defineFlows } from "../../ZISS-Petri-Net/src/wrappers/loader";
|
|
import { IArcExpression } from '../../ZISS-Petri-Net/types/IArcAnnotation';
|
|
import { IJsonSchema } from "../../ZISS-TypeScript-Library/src/JSON";
|
|
import { dynamicSort } from "../../ZISS-TypeScript-Library/src/List-Methods";
|
|
import { deepClone } from "../../ZISS-TypeScript-Library/src/Object-Methods";
|
|
import { analyzeLogic } from "../src/analyze.logic";
|
|
import { IParseableLogic, IParsedLogic, ITransitionDescription } from "../types/interface";
|
|
|
|
|
|
export type THelperFunction = (data: IParsedLogic) => string;
|
|
|
|
export interface IParser {
|
|
mainLoop(context: IParsedLogic): string;
|
|
variableDefinition(context: IParsedLogic): string;
|
|
instanceCreation(context: IParsedLogic): string;
|
|
}
|
|
|
|
export class AbstractParser {
|
|
public variableDefinition(context: IParsedLogic): string {
|
|
throw new Error("Method not implemented.");
|
|
}
|
|
|
|
// Array, containing all Elements which should be replaced.
|
|
protected _replace: {
|
|
regex: RegExp;
|
|
replacer: string;
|
|
}[] = [];
|
|
|
|
/**
|
|
* Function, which will be used to adapt the Path.
|
|
* @param value
|
|
*/
|
|
protected _adaptGuard(
|
|
guard: string,
|
|
simplifiedGuard: string,
|
|
OriginalScope: {
|
|
[index: string]: {
|
|
source: string;
|
|
schema: IJsonSchema;
|
|
};
|
|
},
|
|
simplifiedScope: {
|
|
[index: string]: {
|
|
source: string;
|
|
schema: IJsonSchema;
|
|
};
|
|
},
|
|
mappingOriginalToSimplified: Map<string, string>,
|
|
mappingSimplifiedToOriginal: Map<string, string>,
|
|
mappingSimplifiedToAdapted: Map<string, string>,
|
|
mappingAdaptedToSimplified: Map<string, string>,
|
|
mappingVariableToRoot: Map<string, string>
|
|
): string {
|
|
throw Error("Please Create a Valid Instance");
|
|
}
|
|
|
|
/**
|
|
* Function, which will be used to adapt a Variable Name.
|
|
* @param value The original Variable Name
|
|
*/
|
|
protected _adaptVariableName(
|
|
variable: string,
|
|
simplifiedName: string,
|
|
path: string
|
|
): string {
|
|
throw Error("Please Create a Valid Instance");
|
|
}
|
|
|
|
/**
|
|
* Function, which will be used to generate Function Code.
|
|
* @param taskData
|
|
*/
|
|
protected _getFunctionTriggerCode(taskData): string {
|
|
throw Error("Please Create a Valid Instance");
|
|
}
|
|
|
|
protected _getVariableName(taskData): string {
|
|
throw Error("Please Create a Valid Instance");
|
|
}
|
|
|
|
protected _templates: {
|
|
[index: string]: string;
|
|
} = {};
|
|
|
|
linkTemplates(...args) {
|
|
for (const partial in this._templates) {
|
|
handlebars.registerPartial(partial, this._templates[partial]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Helper Function, to Generate the desired Logic.
|
|
* @param _network
|
|
*/
|
|
parseLogic(_network: ILogicNetwork) {
|
|
let network = deepClone(_network);
|
|
|
|
// Reference to the Own Object.
|
|
const _this = this;
|
|
// Update the Ids.
|
|
network = updateIds(network);
|
|
|
|
// Define the Flow of the Network.
|
|
network = defineFlows(network);
|
|
|
|
const context = analyzeLogic(network, {
|
|
padSizeNames: true,
|
|
// The Adapted Values shouldn't be stored in the Network-Object
|
|
adaptGuard: (...args) => _this._adaptGuard(...args),
|
|
adaptVariableName: (...args) => _this._adaptVariableName(...args)
|
|
});
|
|
|
|
return context;
|
|
}
|
|
|
|
/**
|
|
* Function to Get the Transitions of the Network, Sorted by there Priority
|
|
* @param network The Network Describing the Logic.
|
|
*/
|
|
getTransitionDescriptions(network: ILogicNetwork, sort: 'priority' | 'id' = 'priority'): ITransitionDescription[] {
|
|
const context = this.parseLogic(network);
|
|
const transitions = Array.from(context.transitions.values());
|
|
|
|
transitions.sort(dynamicSort(sort));
|
|
|
|
return transitions;
|
|
}
|
|
|
|
protected _convertInput(definition: {
|
|
// Amount of Tokens that will be consumed (Result must be greater the minTokens)
|
|
consumed: IArcExpression;
|
|
placeId: string;
|
|
type:
|
|
| "expression"
|
|
| "inhibitor"
|
|
| "multiexpression"
|
|
| "test"
|
|
| "value"
|
|
| "variable";
|
|
minTokens: number;
|
|
}): {
|
|
placeId: string;
|
|
minTokens: number;
|
|
tokensToRemove: number;
|
|
} {
|
|
throw Error("Not implemented")
|
|
}
|
|
|
|
protected _convertOutput(definition: {
|
|
// Amount of Tokens that will be produced
|
|
produced: IArcExpression;
|
|
placeId: string;
|
|
type:
|
|
| "expression"
|
|
| "inhibitor"
|
|
| "multiexpression"
|
|
| "test"
|
|
| "value"
|
|
| "variable";
|
|
maxTokens: number;
|
|
}): {
|
|
// Amount of Tokens that will be produced
|
|
placeId: string;
|
|
maxTokens: number;
|
|
tokensToAdd: number;
|
|
} { throw Error("Not implemented") }
|
|
|
|
/**
|
|
*
|
|
* @param network
|
|
*/
|
|
getParseableLogic(network: ILogicNetwork) {
|
|
|
|
const _this = this;
|
|
const context = this.parseLogic(network)
|
|
|
|
|
|
const ret: IParseableLogic = {
|
|
initialMarking: [],
|
|
places: context.places,
|
|
transitions: [],
|
|
transitionsSortedByPriority: [],
|
|
variables: context.variables,
|
|
subscribedVariables: context.subscribedVariables,
|
|
actions: [],
|
|
};
|
|
|
|
const transtionsSortedById = this.getTransitionDescriptions(network, 'id');
|
|
// Iterate over the
|
|
const _createTrans = (idx: number, trans: ITransitionDescription, length: number) => {
|
|
return {
|
|
externalGuard: trans.adaptedExternalGuard,
|
|
dynamicParams: trans.simplifiedDynamicParams,
|
|
id: trans.id,
|
|
consumed: Array.from(trans.inputs.consumed.values()).map(item => _this._convertInput(item)),
|
|
avoided: Array.from(trans.inputs.prevents.values()),
|
|
required: Array.from(trans.inputs.required.values()).map(item => _this._convertInput(item)),
|
|
isAction: trans.isAction,
|
|
label: trans.label,
|
|
logicalGuard: trans.logicalGuard,
|
|
produced: Array.from(trans.outputs.values()).map(item => _this._convertOutput(item)),
|
|
priority: trans.priority,
|
|
scope: trans.simplifiedScope,
|
|
taskID: trans.taskID,
|
|
triggers: trans.triggers,
|
|
functionName: trans.functionName,
|
|
mode: trans.mode,
|
|
params: trans.params,
|
|
isFirst: idx === 0,
|
|
isLast: length - 1 === idx,
|
|
maxTime: trans.maxTime,
|
|
minTime: trans.minTime,
|
|
useMaxTime: trans.useMaxTime,
|
|
useTimes: trans.useTimes,
|
|
locks: trans.locks,
|
|
releases: trans.releases,
|
|
idx,
|
|
}
|
|
}
|
|
|
|
|
|
|
|
for (const [idx, trans] of transtionsSortedById.entries()) {
|
|
const _trans = _createTrans(idx, trans, transtionsSortedById.length);
|
|
ret.transitions.push(_trans);
|
|
if (trans.isAction) {
|
|
ret.actions.push(deepClone(_trans));
|
|
}
|
|
}
|
|
|
|
const transtionsSortedByPriority = this.getTransitionDescriptions(network, 'priority');
|
|
for (const [idx, trans] of transtionsSortedByPriority.entries()) {
|
|
const _trans = _createTrans(idx, trans, transtionsSortedByPriority.length);
|
|
ret.transitionsSortedByPriority.push(_trans);
|
|
}
|
|
|
|
if (ret.actions.length > 0) {
|
|
ret.actions[0].isFirst = true;
|
|
ret.actions[ret.actions.length - 1].isLast = true;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
/**
|
|
* Function, which will generate the MainLoop.
|
|
* @param network
|
|
*/
|
|
mainLoop(network: ILogicNetwork): string {
|
|
throw new Error("Method not implemented.");
|
|
}
|
|
|
|
instanceCreation(context: IParsedLogic): string {
|
|
throw new Error("Method not implemented.");
|
|
}
|
|
}
|