Optimise le calcul des variables manquantes
parent
ac5ec86adb
commit
48b2158ff8
|
@ -1,9 +1,11 @@
|
|||
import {
|
||||
add,
|
||||
map,
|
||||
pluck,
|
||||
any,
|
||||
equals,
|
||||
reduce,
|
||||
mergeWith,
|
||||
chain,
|
||||
length,
|
||||
flatten,
|
||||
|
@ -20,7 +22,10 @@ export let makeJsx = node =>
|
|||
? node.jsx(node.nodeValue, node.explanation)
|
||||
: node.jsx
|
||||
|
||||
export let collectNodeMissing = node => node.missingVariables || []
|
||||
export let collectNodeMissing = node => node.missingVariables || {}
|
||||
|
||||
export let mergeAllMissing = missings => reduce(mergeWith(add),{},map(collectNodeMissing,missings))
|
||||
export let mergeMissing = (left, right) => mergeWith(add, left || {}, right || {})
|
||||
|
||||
export let evaluateNode = (cache, situationGate, parsedRules, node) =>
|
||||
node.evaluate ? node.evaluate(cache, situationGate, parsedRules, node) : node
|
||||
|
@ -46,8 +51,8 @@ export let evaluateArray = (reducer, start) => (
|
|||
? null
|
||||
: reduce(reducer, start, values),
|
||||
missingVariables = node.nodeValue == null
|
||||
? map(collectNodeMissing, explanation)
|
||||
: []
|
||||
? mergeAllMissing(explanation)
|
||||
: {}
|
||||
// console.log("".padStart(cache.parseLevel),map(node => length(flatten(collectNodeMissing(node))) ,explanation))
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -69,10 +74,8 @@ export let evaluateArrayWithFilter = (evaluationFilter, reducer, start) => (
|
|||
? null
|
||||
: reduce(reducer, start, values),
|
||||
missingVariables = node.nodeValue == null
|
||||
// TODO - this works by coincidence, composantes are usually of a computation
|
||||
// where missing variables are shared
|
||||
? uniq(map(collectNodeMissing, explanation))
|
||||
: []
|
||||
? mergeAllMissing(explanation)
|
||||
: {}
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -98,7 +101,7 @@ export let evaluateObject = (objectShape, effect) => (
|
|||
let transforms = map(k => [k, evaluateOne], keys(objectShape)),
|
||||
explanation = evolve(fromPairs(transforms))(node.explanation),
|
||||
nodeValue = effect(explanation),
|
||||
missingVariables = map(collectNodeMissing, values(explanation))
|
||||
missingVariables = mergeAllMissing(values(explanation))
|
||||
// console.log("".padStart(cache.parseLevel),map(node => length(flatten(collectNodeMissing(node))) ,explanation))
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
flatten,
|
||||
mergeAll,
|
||||
pluck,
|
||||
groupBy,
|
||||
toPairs,
|
||||
|
@ -39,14 +40,10 @@ import { findRuleByDottedName, disambiguateRuleReference } from './rules'
|
|||
missingVariables: {variable: [objectives]}
|
||||
*/
|
||||
|
||||
export let collectMissingVariables = targets => {
|
||||
let missing = flatten(pluck('missingVariables', targets))
|
||||
// console.log("total # missing", length(missing))
|
||||
return groupBy(identity, missing)
|
||||
}
|
||||
export let collectMissingVariables = targets => mergeAll(pluck('missingVariables', targets))
|
||||
|
||||
export let getNextSteps = (situationGate, analysis) => {
|
||||
let impact = ([, objectives]) => length(objectives)
|
||||
let impact = ([, count]) => count
|
||||
|
||||
let missingVariables = collectMissingVariables(analysis.targets),
|
||||
pairs = toPairs(missingVariables),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import {
|
||||
flatten,
|
||||
mergeAll,
|
||||
length,
|
||||
objOf,
|
||||
toPairs,
|
||||
|
@ -42,7 +43,9 @@ import {
|
|||
evaluateArrayWithFilter,
|
||||
evaluateObject,
|
||||
parseObject,
|
||||
collectNodeMissing
|
||||
collectNodeMissing,
|
||||
mergeAllMissing,
|
||||
mergeMissing
|
||||
} from './evaluation'
|
||||
import {
|
||||
findRuleByName,
|
||||
|
@ -151,14 +154,12 @@ let devariate = (recurse, k, v) => {
|
|||
nodeValue = choice ? choice.nodeValue : null
|
||||
|
||||
let leftMissing = choice
|
||||
? []
|
||||
: uniq(
|
||||
map(collectNodeMissing, pluck('condition', explanation))
|
||||
),
|
||||
? {}
|
||||
: mergeAllMissing(pluck('condition', explanation)),
|
||||
rightMissing = !choice
|
||||
? []
|
||||
: map(collectNodeMissing, satisfied),
|
||||
missingVariables = concat(leftMissing, rightMissing || [])
|
||||
? {}
|
||||
: mergeAllMissing(satisfied),
|
||||
missingVariables = mergeMissing(leftMissing, rightMissing)
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -222,7 +223,7 @@ export let mecanismOneOf = (recurse, k, v) => {
|
|||
nodeValue = any(equals(true), values)
|
||||
? true
|
||||
: any(equals(null), values) ? null : false,
|
||||
missingVariables = nodeValue == null ? uniq(map(collectNodeMissing, explanation)) : []
|
||||
missingVariables = nodeValue == null ? mergeAllMissing(explanation) : {}
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -265,7 +266,7 @@ export let mecanismAllOf = (recurse, k, v) => {
|
|||
nodeValue = any(equals(false), values)
|
||||
? false // court-circuit
|
||||
: any(equals(null), values) ? null : true,
|
||||
missingVariables = nodeValue == null ? map(collectNodeMissing, explanation) : []
|
||||
missingVariables = nodeValue == null ? mergeAllMissing(explanation) : {}
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -311,8 +312,8 @@ export let mecanismNumericalSwitch = (recurse, k, v) => {
|
|||
investigate = explanation.condition.nodeValue !== false,
|
||||
missingOnTheRight = investigate
|
||||
? explanation.consequence.missingVariables
|
||||
: [],
|
||||
missingVariables = concat(missingOnTheLeft || [], missingOnTheRight || [])
|
||||
: {},
|
||||
missingVariables = mergeMissing(missingOnTheLeft, missingOnTheRight)
|
||||
|
||||
return {
|
||||
...node,
|
||||
|
@ -359,7 +360,7 @@ export let mecanismNumericalSwitch = (recurse, k, v) => {
|
|||
choice = find(node => node.condValue, explanation),
|
||||
missingVariables = choice
|
||||
? choice.missingVariables
|
||||
: map(collectNodeMissing, explanation)
|
||||
: mergeAllMissing(explanation)
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -426,7 +427,7 @@ let doInversion = (oldCache, situationGate, parsedRules, v, dottedName) => {
|
|||
|
||||
if (inversion.inversionChoiceNeeded)
|
||||
return {
|
||||
missingVariables: [dottedName],
|
||||
missingVariables: {[dottedName]:1},
|
||||
nodeValue: null
|
||||
}
|
||||
let { fixedObjectiveValue, fixedObjectiveRule } = inversion
|
||||
|
@ -461,7 +462,7 @@ let doInversion = (oldCache, situationGate, parsedRules, v, dottedName) => {
|
|||
|
||||
return {
|
||||
nodeValue,
|
||||
missingVariables: [],
|
||||
missingVariables: {},
|
||||
inversionCache
|
||||
}
|
||||
}
|
||||
|
@ -473,7 +474,7 @@ export let mecanismInversion = dottedName => (recurse, k, v) => {
|
|||
situationGate(dottedName) == undefined &&
|
||||
doInversion(cache, situationGate, parsedRules, v, dottedName),
|
||||
nodeValue = inversion.nodeValue,
|
||||
missingVariables = uniq(flatten(inversion.missingVariables))
|
||||
missingVariables = inversion.missingVariables
|
||||
|
||||
let evaluatedNode = rewriteNode(node, nodeValue, null, missingVariables)
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
divide,
|
||||
multiply,
|
||||
map,
|
||||
merge,
|
||||
length,
|
||||
flatten,
|
||||
intersection,
|
||||
|
@ -57,7 +58,9 @@ import {
|
|||
import {
|
||||
evaluateNode,
|
||||
rewriteNode,
|
||||
makeJsx
|
||||
makeJsx,
|
||||
mergeMissing,
|
||||
mergeAllMissing
|
||||
} from './evaluation'
|
||||
import {
|
||||
anyNull,
|
||||
|
@ -152,10 +155,10 @@ let fillVariableNode = (rules, rule, filter) => parseResult => {
|
|||
? parsedRule.nodeValue // la valeur du calcul fait foi
|
||||
: null, // elle restera donc nulle
|
||||
missingVariables = nodeValue != null // notamment si situationValue != null
|
||||
? []
|
||||
? {}
|
||||
: variableIsCalculable
|
||||
? parsedRule.missingVariables
|
||||
: [dottedName]
|
||||
: {[dottedName]:1}
|
||||
|
||||
cache[cacheName] = rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
return cache[cacheName]
|
||||
|
@ -300,9 +303,9 @@ let treat = (rules, rule) => rawNode => {
|
|||
value1 == null || value2 == null
|
||||
? null
|
||||
: operatorFunction(value1, value2),
|
||||
missingVariables = concat(
|
||||
explanation[0].missingVariables || [],
|
||||
explanation[1].missingVariables || [])
|
||||
missingVariables = mergeMissing(
|
||||
explanation[0].missingVariables,
|
||||
explanation[1].missingVariables)
|
||||
|
||||
return rewriteNode(node, nodeValue, explanation, missingVariables)
|
||||
}
|
||||
|
@ -407,7 +410,7 @@ let treat = (rules, rule) => rawNode => {
|
|||
sélection: mecanismSelection,
|
||||
'une possibilité': always({
|
||||
'une possibilité': 'oui',
|
||||
missingVariables: [rule.dottedName]
|
||||
missingVariables: {[rule.dottedName]:1}
|
||||
}),
|
||||
inversion: mecanismInversion(rule.dottedName),
|
||||
allègement: mecanismReduction
|
||||
|
@ -480,16 +483,16 @@ export let treatRuleRoot = (rules, rule) => {
|
|||
|
||||
let condMissing =
|
||||
val(notApplicable) === true
|
||||
? []
|
||||
? {}
|
||||
: val(applicable) === false
|
||||
? []
|
||||
: concat(
|
||||
(notApplicable && notApplicable.missingVariables) || [],
|
||||
(applicable && applicable.missingVariables) || []
|
||||
? {}
|
||||
: merge(
|
||||
(notApplicable && notApplicable.missingVariables) || {},
|
||||
(applicable && applicable.missingVariables) || {}
|
||||
),
|
||||
collectInFormule = isApplicable !== false,
|
||||
formMissing = (collectInFormule && formule.missingVariables) || [],
|
||||
missingVariables = concat(condMissing, formMissing)
|
||||
formMissing = (collectInFormule && formule.missingVariables) || {},
|
||||
missingVariables = mergeMissing(condMissing, formMissing)
|
||||
|
||||
cache.parseLevel--
|
||||
// console.log("".padStart(cache.parseLevel-1),map(mv => length(flatten(mv)), {ruleCond:condMissing, formule:formMissing}))
|
||||
|
|
Loading…
Reference in New Issue