From 70f99787f45f82c6482b3182a45e603b1f4c2f64 Mon Sep 17 00:00:00 2001 From: Johan Girod Date: Tue, 20 Apr 2021 15:45:55 +0200 Subject: [PATCH] =?UTF-8?q?:bug:=20R=C3=A9pare=20un=20bug=20dans=20le=20m?= =?UTF-8?q?=C3=A9canisme=20r=C3=A9soudre=20le=20cycle?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Le cache n'était pas réinitialisé, et les valeurs utilisée étaient celle du dernier calcul de la fonction uniroot, qui n'est pas forcément celui du résultat finalement retourné. --- publicodes/CHANGELOG.md | 6 ++++ publicodes/core/source/AST/types.ts | 4 +-- publicodes/core/source/mecanisms/recalcul.ts | 6 ++-- .../résoudre-référence-circulaire.ts | 17 ++++++----- publicodes/core/source/rule.ts | 2 +- .../résoudre-référence-circulaire.yaml | 30 ++++++++++--------- .../ui-react/source/mecanisms/Recalcul.tsx | 5 ++-- 7 files changed, 40 insertions(+), 30 deletions(-) diff --git a/publicodes/CHANGELOG.md b/publicodes/CHANGELOG.md index 041cff1ab..8507b2857 100644 --- a/publicodes/CHANGELOG.md +++ b/publicodes/CHANGELOG.md @@ -25,3 +25,9 @@ **core** - Fix bug sur le mécanisme minimum, une valeur non applicable n'est plus considérée comme valant "0" (#1493) + +## 1.0.0-beta.16 (release candidate) + +**core** + +- Répare un bug dans le mécanisme résoudre le cycle diff --git a/publicodes/core/source/AST/types.ts b/publicodes/core/source/AST/types.ts index 92349e638..e732c828a 100644 --- a/publicodes/core/source/AST/types.ts +++ b/publicodes/core/source/AST/types.ts @@ -17,7 +17,7 @@ import { PlafondNode } from '../mecanisms/plafond' import { PlancherNode } from '../mecanisms/plancher' import { ProductNode } from '../mecanisms/product' import { RecalculNode } from '../mecanisms/recalcul' -import { RésoudreRéférenceCiruclaireNode } from '../mecanisms/résoudre-référence-circulaire' +import { RésoudreRéférenceCirculaireNode } from '../mecanisms/résoudre-référence-circulaire' import { SituationNode } from '../mecanisms/situation' import { SommeNode } from '../mecanisms/sum' import { SynchronisationNode } from '../mecanisms/synchronisation' @@ -58,7 +58,7 @@ export type ASTNode = ( | PlancherNode | ProductNode | RecalculNode - | RésoudreRéférenceCiruclaireNode + | RésoudreRéférenceCirculaireNode | SituationNode | SommeNode | SynchronisationNode diff --git a/publicodes/core/source/mecanisms/recalcul.ts b/publicodes/core/source/mecanisms/recalcul.ts index b5cbaef07..3b7ce082e 100644 --- a/publicodes/core/source/mecanisms/recalcul.ts +++ b/publicodes/core/source/mecanisms/recalcul.ts @@ -32,12 +32,12 @@ const evaluateRecalcul: EvaluationFunction<'recalcul'> = function (node) { ) as Array<[ReferenceNode & EvaluatedNode, EvaluatedNode]> const originalCache = this.cache - const originalSituation = { ...this.parsedSituation } + const originalSituation = this.parsedSituation // Optimisation : no need for recalcul if situation is the same const invalidateCache = Object.keys(amendedSituation).length > 0 if (invalidateCache) { this.resetCache() - this.cache._meta = { ...this.cache._meta, inRecalcul: true } + this.cache._meta.inRecalcul = true } this.parsedSituation = { @@ -55,10 +55,12 @@ const evaluateRecalcul: EvaluationFunction<'recalcul'> = function (node) { } const evaluatedNode = this.evaluate(node.explanation.recalcul) + this.parsedSituation = originalSituation if (invalidateCache) { this.cache = originalCache } + return { ...node, nodeValue: evaluatedNode.nodeValue, diff --git a/publicodes/core/source/mecanisms/résoudre-référence-circulaire.ts b/publicodes/core/source/mecanisms/résoudre-référence-circulaire.ts index ba41f122a..1dee33ea1 100644 --- a/publicodes/core/source/mecanisms/résoudre-référence-circulaire.ts +++ b/publicodes/core/source/mecanisms/résoudre-référence-circulaire.ts @@ -6,7 +6,7 @@ import { Context } from '../parsePublicodes' import uniroot from '../uniroot' import { UnitéNode } from './unité' -export type RésoudreRéférenceCiruclaireNode = { +export type RésoudreRéférenceCirculaireNode = { explanation: { ruleToSolve: string valeur: ASTNode @@ -65,19 +65,20 @@ export const evaluateRésoudreRéférenceCirculaire: EvaluationFunction<'résoud const defaultMin = -1_000_000 const defaultMax = 100_000_000 - nodeValue = uniroot(test, defaultMin, defaultMax, 1, 30, 2) + nodeValue = uniroot(test, defaultMin, defaultMax, 0.5, 30, 2) } + + this.cache = originalCache + delete this.parsedSituation[node.explanation.ruleToSolve] + if (nodeValue === undefined) { nodeValue = null this.cache._meta.inversionFail = true } - if (nodeValue != null) { - originalCache.nodes.forEach((v, k) => this.cache.nodes.set(k, v)) + if (nodeValue !== null) { + valeur = evaluateWithValue(nodeValue, unit) } - // console.log('iteration résoudre référence circulaire :', i) - this.cache = originalCache - delete this.parsedSituation[node.explanation.ruleToSolve] return { ...node, unit, @@ -98,7 +99,7 @@ export default function parseRésoudreRéférenceCirculaire(v, context: Context) valeur: parse(v.valeur, context), }, nodeKind: 'résoudre référence circulaire', - } as RésoudreRéférenceCiruclaireNode + } as RésoudreRéférenceCirculaireNode } parseRésoudreRéférenceCirculaire.nom = 'résoudre la référence circulaire' diff --git a/publicodes/core/source/rule.ts b/publicodes/core/source/rule.ts index 172deed64..134ff24b3 100644 --- a/publicodes/core/source/rule.ts +++ b/publicodes/core/source/rule.ts @@ -165,7 +165,6 @@ registerEvaluationFunction('rule', function evaluate(node) { explanation.valeur = valeur } - // if (valeur.nodeValue === '') { const evaluation = { ...node, @@ -177,5 +176,6 @@ registerEvaluationFunction('rule', function evaluate(node) { ), ...(valeur && 'unit' in valeur && { unit: valeur.unit }), } + return evaluation }) diff --git a/publicodes/core/test/mécanismes/résoudre-référence-circulaire.yaml b/publicodes/core/test/mécanismes/résoudre-référence-circulaire.yaml index 841abfefb..7b006df0a 100644 --- a/publicodes/core/test/mécanismes/résoudre-référence-circulaire.yaml +++ b/publicodes/core/test/mécanismes/résoudre-référence-circulaire.yaml @@ -37,15 +37,16 @@ cycle avec inversion et situation vide: situation: cycle avec inversion et situation vide: CA valeur attendue: null - # - nom: net - # situation: - # cycle avec inversion et situation vide: net - # valeur attendue: null - # - nom: net après impôt - # situation: - # cycle avec inversion et situation vide: net après impôt - # valeur attendue: null + - nom: net + situation: + cycle avec inversion et situation vide: net + valeur attendue: null + - nom: net après impôt + situation: + cycle avec inversion et situation vide: net après impôt + valeur attendue: null +# TODO : à corriger cycle avec la règle à inverser fixée dans la situation: valeur: net exemples: @@ -53,13 +54,14 @@ cycle avec la règle à inverser fixée dans la situation: CA: 10000 valeur attendue: 6666.666 -cycle avec la règle du cycle fixée dans la situation: - valeur: CA - exemples: - - situation: - net: 1000 - valeur attendue: 1500 +# cycle avec la règle du cycle fixée dans la situation: +# valeur: CA +# exemples: +# - situation: +# net: 1000 +# valeur attendue: 1500 +# TODO : à corriger # cycle avec une règle reliée fixée dans la situation: # valeur: net # exemples: diff --git a/publicodes/ui-react/source/mecanisms/Recalcul.tsx b/publicodes/ui-react/source/mecanisms/Recalcul.tsx index 14c6d346d..c96381df6 100644 --- a/publicodes/ui-react/source/mecanisms/Recalcul.tsx +++ b/publicodes/ui-react/source/mecanisms/Recalcul.tsx @@ -8,9 +8,8 @@ export default function Recalcul({ nodeValue, explanation, unit }) { <> {explanation.recalcul && ( <> - Recalcul de la règle{' '} - {' '} - avec les valeurs suivantes : + Recalcul de la valeur de {' '} + avec la situation suivante : )}