])
}
}
/>
return {
explanation,
evaluate,
jsx,
category: 'mecanism',
name: 'variations',
type: 'numeric'
}
}
export let mecanismOneOf = (recurse, k, v) => {
if (!R.is(Array,v)) throw 'should be array'
let explanation = R.map(recurse, v)
let jsx = (nodeValue, explanation) =>
{explanation.map(item =>
{makeJsx(item)}
)}
}
/>
let evaluate = (situationGate, parsedRules, node) => {
let evaluateOne = child => evaluateNode(situationGate, parsedRules, child),
explanation = R.map(evaluateOne, node.explanation),
values = R.pluck("nodeValue",explanation),
nodeValue = R.any(R.equals(true),values) ? true :
(R.any(R.equals(null),values) ? null : false)
let collectMissing = node => node.nodeValue == null ? R.chain(collectNodeMissing,node.explanation) : []
return rewriteNode(node,nodeValue,explanation,collectMissing)
}
return {
evaluate,
jsx,
explanation,
category: 'mecanism',
name: 'une de ces conditions',
type: 'boolean'
}
}
export let mecanismAllOf = (recurse, k,v) => {
if (!R.is(Array,v)) throw 'should be array'
let explanation = R.map(recurse, v)
let jsx = (nodeValue, explanation) =>
{explanation.map(item =>
{makeJsx(item)}
)}
}
/>
return {
evaluate: evaluateArray(R.and,true),
jsx,
explanation,
category: 'mecanism',
name: 'toutes ces conditions',
type: 'boolean'
}
}
export let mecanismNumericalSwitch = (recurse, k,v) => {
// Si "l'aiguillage" est une constante ou une référence directe à une variable;
// l'utilité de ce cas correspond à un appel récursif au mécanisme
if (R.is(String,v)) return recurse(v)
if (!R.is(Object,v) || R.keys(v).length == 0) {
throw 'Le mécanisme "aiguillage numérique" et ses sous-logiques doivent contenir au moins une proposition'
}
// les termes sont les couples (condition, conséquence) de l'aiguillage numérique
let terms = R.toPairs(v)
// la conséquence peut être un 'string' ou un autre aiguillage numérique
let parseCondition = ([condition, consequence]) => {
let
conditionNode = recurse(condition), // can be a 'comparison', a 'variable', TODO a 'negation'
consequenceNode = mecanismNumericalSwitch(recurse, condition, consequence)
let evaluate = (situationGate, parsedRules, node) => {
let collectMissing = node => {
let missingOnTheLeft = collectNodeMissing(node.explanation.condition),
investigate = node.explanation.condition.nodeValue !== false,
missingOnTheRight = investigate ? collectNodeMissing(node.explanation.consequence) : []
return R.concat(missingOnTheLeft, missingOnTheRight)
}
let explanation = R.evolve({
condition: R.curry(evaluateNode)(situationGate, parsedRules),
consequence: R.curry(evaluateNode)(situationGate, parsedRules)
}, node.explanation)
return {
...node,
collectMissing,
explanation,
nodeValue: explanation.consequence.nodeValue,
condValue: explanation.condition.nodeValue
}
}
let jsx = (nodeValue, {condition, consequence}) =>
{makeJsx(condition)}
{makeJsx(consequence)}
return {
evaluate,
jsx,
explanation: {condition: conditionNode, consequence: consequenceNode},
category: 'condition',
text: condition,
condition: conditionNode,
type: 'boolean',
}
}
let evaluateTerms = (situationGate, parsedRules, node) => {
let
evaluateOne = child => evaluateNode(situationGate, parsedRules, child),
explanation = R.map(evaluateOne, node.explanation),
choice = R.find(node => node.condValue, explanation),
nonFalsyTerms = R.filter(node => node.condValue !== false, explanation),
getFirst = (prop) => R.pipe(R.head, R.prop(prop))(nonFalsyTerms),
nodeValue =
// voilà le "numérique" dans le nom de ce mécanisme : il renvoie zéro si aucune condition n'est vérifiée
R.isEmpty(nonFalsyTerms) ? 0 :
// c'est un 'null', on renvoie null car des variables sont manquantes
getFirst('condValue') == null ? null :
// c'est un true, on renvoie la valeur de la conséquence
getFirst('nodeValue')
let collectMissing = node => {
let choice = R.find(node => node.condValue, node.explanation)
return choice ? collectNodeMissing(choice) : R.chain(collectNodeMissing,node.explanation)
}
return rewriteNode(node,nodeValue,explanation,collectMissing)
}
let explanation = R.map(parseCondition,terms)
let jsx = (nodeValue, explanation) =>
{explanation.map(item =>