From d24a6b3908fb1efce4b0cc8b8f62bd2f2d759b7d Mon Sep 17 00:00:00 2001 From: Laurent Bossavit Date: Tue, 10 Apr 2018 13:00:03 +0200 Subject: [PATCH] Simplifie le calcul des variables manquantes --- source/engine/evaluation.js | 44 ++++++++++++++++++++++++------------- source/engine/traverse.js | 42 +++++++++++++++-------------------- 2 files changed, 47 insertions(+), 39 deletions(-) diff --git a/source/engine/evaluation.js b/source/engine/evaluation.js index c0df56734..c8df9d8a6 100644 --- a/source/engine/evaluation.js +++ b/source/engine/evaluation.js @@ -18,16 +18,17 @@ export let makeJsx = node => : node.jsx export let collectNodeMissing = node => - node.collectMissing ? node.collectMissing(node) : [] + node.missingVariables || + (node.collectMissing ? node.collectMissing(node) : []) export let evaluateNode = (cache, situationGate, parsedRules, node) => node.evaluate ? node.evaluate(cache, situationGate, parsedRules, node) : node -export let rewriteNode = (node, nodeValue, explanation, collectMissing) => ({ +export let rewriteNode = (node, nodeValue, explanation, collectMissing = null) => ({ ...node, nodeValue, - collectMissing, - explanation + explanation, + collectMissing }) export let evaluateArray = (reducer, start) => ( @@ -42,11 +43,15 @@ export let evaluateArray = (reducer, start) => ( values = pluck('nodeValue', explanation), nodeValue = any(equals(null), values) ? null - : reduce(reducer, start, values) + : reduce(reducer, start, values), + missingVariables = node.nodeValue == null + ? chain(collectNodeMissing, explanation) + : [] - let collectMissing = node => - node.nodeValue == null ? chain(collectNodeMissing, node.explanation) : [] - return rewriteNode(node, nodeValue, explanation, collectMissing) + return { + ...rewriteNode(node, nodeValue, explanation), + missingVariables + } } export let evaluateArrayWithFilter = (evaluationFilter, reducer, start) => ( @@ -64,10 +69,15 @@ export let evaluateArrayWithFilter = (evaluationFilter, reducer, start) => ( values = pluck('nodeValue', explanation), nodeValue = any(equals(null), values) ? null - : reduce(reducer, start, values) + : reduce(reducer, start, values), + missingVariables = node.nodeValue == null + ? chain(collectNodeMissing, explanation) + : [] - let collectMissing = node => chain(collectNodeMissing, node.explanation) - return rewriteNode(node, nodeValue, explanation, collectMissing) + return { + ...rewriteNode(node, nodeValue, explanation), + missingVariables + } } export let parseObject = (recurse, objectShape, value) => { @@ -86,11 +96,15 @@ export let evaluateObject = (objectShape, effect) => ( node ) => { let evaluateOne = child => - evaluateNode(cache, situationGate, parsedRules, child), - collectMissing = node => chain(collectNodeMissing, values(node.explanation)) + evaluateNode(cache, situationGate, parsedRules, child) let transforms = map(k => [k, evaluateOne], keys(objectShape)), explanation = evolve(fromPairs(transforms))(node.explanation), - nodeValue = effect(explanation) - return rewriteNode(node, nodeValue, explanation, collectMissing) + nodeValue = effect(explanation), + missingVariables = chain(collectNodeMissing, values(explanation)) + + return { + ...rewriteNode(node, nodeValue, explanation), + missingVariables + } } diff --git a/source/engine/traverse.js b/source/engine/traverse.js index 6662804ed..4cfa225a5 100644 --- a/source/engine/traverse.js +++ b/source/engine/traverse.js @@ -151,29 +151,17 @@ let fillVariableNode = (rules, rule, filter) => parseResult => { ? parsedRule.nodeValue // la valeur du calcul fait foi : null, // elle restera donc nulle explanation = parsedRule, - missingVariables = variableIsCalculable ? [] : [dottedName] - - let collectMissing = node => { - let missingName = cacheName + ':missing', - cached = cache[missingName] - - if (cached) return cached - - let result = - nodeValue != null // notamment si situationValue != null + missingVariables = nodeValue != null // notamment si situationValue != null ? [] : variableIsCalculable ? collectNodeMissing(parsedRule) - : node.missingVariables - cache[missingName] = result - return result - } + : [dottedName] if (cached) { return cached } else { cache[cacheName] = { - ...rewriteNode(node, nodeValue, explanation, collectMissing), + ...rewriteNode(node, nodeValue, explanation), missingVariables } return cache[cacheName] @@ -212,9 +200,13 @@ let buildNegatedVariable = variable => { parsedRules, node.explanation ), - nodeValue = explanation.nodeValue == null ? null : !explanation.nodeValue - let collectMissing = node => collectNodeMissing(node.explanation) - return rewriteNode(node, nodeValue, explanation, collectMissing) + nodeValue = explanation.nodeValue == null ? null : !explanation.nodeValue, + missingVariables = explanation.missingVariables + + return { + ...rewriteNode(node, nodeValue, explanation), + missingVariables + } } let jsx = (nodeValue, explanation) => ( @@ -317,12 +309,14 @@ let treat = (rules, rule) => rawNode => { nodeValue = value1 == null || value2 == null ? null - : operatorFunction(value1, value2) + : operatorFunction(value1, value2), + missingVariables = chain(collectNodeMissing, explanation) - let collectMissing = node => - chain(collectNodeMissing, node.explanation) - return rewriteNode(node, nodeValue, explanation, collectMissing) + return { + ...rewriteNode(node, nodeValue, explanation), + missingVariables + } } let fillFiltered = parseResult => @@ -425,7 +419,7 @@ let treat = (rules, rule) => rawNode => { sélection: mecanismSelection, 'une possibilité': always({ 'une possibilité': 'oui', - collectMissing: () => [rule.dottedName] + missingVariables: [rule.dottedName] }), inversion: mecanismInversion(rule.dottedName), allègement: mecanismReduction @@ -461,7 +455,7 @@ export let treatRuleRoot = (rules, rule) => { Aujourd'hui, une règle peut avoir (comme propriétés à parser) `non applicable si` et `formule`, qui ont elles-mêmes des propriétés de type mécanisme (ex. barème) ou des expressions en ligne (ex. maVariable + 3). Ces mécanismes où variables sont descendues à leur tour grâce à `treat()`. - Lors de ce traitement, des fonctions 'evaluate', `collectMissingVariables` et `jsx` sont attachés aux objets de l'AST + Lors de ce traitement, des fonctions 'evaluate' et `jsx` sont attachés aux objets de l'AST */ let evaluate = (cache, situationGate, parsedRules, r) => { let evolveRule = curry(evaluateNode)(cache, situationGate, parsedRules),