diff --git a/source/.eslintrc.yaml b/source/.eslintrc.yaml index bf550be7c..9e967408a 100644 --- a/source/.eslintrc.yaml +++ b/source/.eslintrc.yaml @@ -8,6 +8,9 @@ rules: semi: - 1 - never + quotes: + - 1 + - single no-unused-vars: 1 no-console: 1 no-global-assign: 0 diff --git a/source/engine/rules.js b/source/engine/rules.js index b1b605bf0..447bd672e 100644 --- a/source/engine/rules.js +++ b/source/engine/rules.js @@ -64,7 +64,9 @@ export let disambiguateRuleReference = (allRules, {ns, name}, partialName) => { )(findRuleByDottedName(allRules, [...path, partialName].join(' . '))) , null, pathPossibilities) - return found && found.dottedName || do {throw `OUUUUPS la référence '${partialName}' dans la règle '${name}' est introuvable dans la base`} + return found && found.dottedName || do { + throw `OUUUUPS la référence '${partialName}' dans la règle '${name}' est introuvable dans la base` + } } // On enrichit la base de règles avec des propriétés dérivées de celles du YAML diff --git a/source/engine/traverse-common-functions.js b/source/engine/traverse-common-functions.js index c753f5cce..5d4e034e6 100644 --- a/source/engine/traverse-common-functions.js +++ b/source/engine/traverse-common-functions.js @@ -1,5 +1,9 @@ import R from 'ramda' -export let val = node => node.nodeValue +export let val = node => node && node.nodeValue + +export let undefOrTrue = val => val == undefined || val == true export let anyNull = R.any(R.pipe(val, R.equals(null))) + +export let applyOrEmpty = func => v => v ? func(v) : [] diff --git a/source/engine/traverse.js b/source/engine/traverse.js index 9f7075ff0..1fd8720f9 100644 --- a/source/engine/traverse.js +++ b/source/engine/traverse.js @@ -12,6 +12,7 @@ import { mecanismSelection } from "./mecanisms" import {evaluateNode, rewriteNode, collectNodeMissing, makeJsx} from './evaluation' +import {anyNull, val, undefOrTrue, applyOrEmpty} from './traverse-common-functions' let nearley = () => new Parser(Grammar.ParserRules, Grammar.ParserStart) @@ -332,74 +333,67 @@ let treat = (rules, rule) => rawNode => { } //TODO c'est moche : -export let computeRuleValue = (formuleValue, condValue) => - condValue === undefined +export let computeRuleValue = (formuleValue, isApplicable) => + isApplicable === true ? formuleValue - : formuleValue === 0 + : isApplicable === false ? 0 - : condValue === null ? null : condValue === true ? 0 : formuleValue + : formuleValue == 0 + ? 0 + : null export let treatRuleRoot = (rules, rule) => { let evaluate = (situationGate, parsedRules, r) => { let + evolveRule = R.curry(evaluateNode)(situationGate, parsedRules), evaluated = R.evolve({ - formule: R.curry(evaluateNode)(situationGate, parsedRules), - "non applicable si": R.curry(evaluateNode)(situationGate, parsedRules) - },r), - formuleValue = evaluated.formule && evaluated.formule.nodeValue, - condition = R.prop('non applicable si',evaluated), - condValue = condition && condition.nodeValue, - nodeValue = computeRuleValue(formuleValue, condValue) + 'formule': evolveRule, + 'non applicable si': evolveRule, + 'applicable si': evolveRule + }, r), + //evaluateed = console.log('evaluated', evaluated), + formuleValue = val(evaluated['formule']), + isApplicable = do { let e = evaluated + val(e['non applicable si']) === true + ? false + : val(e['applicable si']) === false + ? false + : anyNull( [e['non applicable si'], e['applicable si']] ) + ? null + : !val(e['non applicable si']) && undefOrTrue(val(e['applicable si'])) + }, + nodeValue = computeRuleValue(formuleValue, isApplicable) + //ya = console.log(r.name, val(evaluated['applicable si']), val(evaluated['non applicable si'])) + //console.log('evaluate', evaluated['applicable si']) + //ya = console.log(r.name, 'formuleValue, condValue',formuleValue, condValue) - return {...evaluated, nodeValue} + return {...evaluated, nodeValue, isApplicable} } - let collectMissing = node => { - let cond = R.prop('non applicable si',node), - condMissing = cond ? collectNodeMissing(cond) : [], - collectInFormule = (cond && cond.nodeValue != undefined) ? !cond.nodeValue : true, - formule = node.formule, - formMissing = collectInFormule ? (formule ? collectNodeMissing(formule) : []) : [] + let collectMissing = ({ + formule, + isApplicable, + 'non applicable si': notApplicable, + 'applicable si': applicable}) => { + + let + condMissing = R.chain( + applyOrEmpty(collectNodeMissing) + )([notApplicable, applicable]), + collectInFormule = isApplicable !== false, + formMissing = applyOrEmpty( + () => applyOrEmpty(collectNodeMissing)(formule) + )(collectInFormule) return R.concat(condMissing,formMissing) } - let parsedRoot = R.evolve({ // Voilà les attributs d'une règle qui sont aujourd'hui dynamiques, donc à traiter + let parsedRoot = R.evolve({ + // Voilà les attributs d'une règle qui sont aujourd'hui dynamiques, donc à traiter + // Les métadonnées d'une règle n'en font pas aujourd'hui partie - // Les métadonnées d'une règle n'en font pas aujourd'hui partie - - // condition d'applicabilité de la règle - 'non applicable si': value => { - let evaluate = (situationGate, parsedRules, node) => { - let collectMissing = node => collectNodeMissing(node.explanation) - let explanation = evaluateNode(situationGate, parsedRules, node.explanation), - nodeValue = explanation.nodeValue - return rewriteNode(node,nodeValue,explanation,collectMissing) - } - - let child = treat(rules, rule)(value) - - let jsx = (nodeValue, explanation) => - {makeJsx(explanation)} - : makeJsx(explanation) - } - /> - - return { - evaluate, - jsx, - category: 'ruleProp', - rulePropType: 'cond', - name: 'non applicable si', - type: 'boolean', - explanation: child - } - } - , + // condition d'applicabilité de la règle + 'non applicable si': evolveCond('non applicable si', rule, rules), + 'applicable si': evolveCond('applicable si', rule, rules), 'formule': value => { let evaluate = (situationGate, parsedRules, node) => { let collectMissing = node => collectNodeMissing(node.explanation) @@ -423,8 +417,6 @@ export let treatRuleRoot = (rules, rule) => { explanation: child } } - , - })(rule) return { @@ -435,6 +427,42 @@ export let treatRuleRoot = (rules, rule) => { } } +let evolveCond = (name, rule, rules) => value => { + let evaluate = (situationGate, parsedRules, node) => { + let collectMissing = node => collectNodeMissing(node.explanation) + let explanation = evaluateNode(situationGate, parsedRules, node.explanation), + nodeValue = explanation.nodeValue + return rewriteNode(node,nodeValue,explanation,collectMissing) + } + + let child = treat(rules, rule)(value) + + let jsx = (nodeValue, explanation) => ( + {makeJsx(explanation)} + ) : ( + makeJsx(explanation) + ) + } + /> + ) + + return { + evaluate, + jsx, + category: 'ruleProp', + rulePropType: 'cond', + name, + type: 'boolean', + explanation: child + } +} + export let analyseSituation = (rules, rootVariable) => situationGate => { let {root, parsedRules} = analyseTopDown(rules,rootVariable)(situationGate)