Simplifie le calcul des variables manquantes

pull/197/head
Laurent Bossavit 2018-04-10 13:00:03 +02:00
parent 0f58a569af
commit d24a6b3908
2 changed files with 47 additions and 39 deletions

View File

@ -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
}
}

View File

@ -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 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),