Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supprime les variables temporelles de publicodes #1579

Merged
merged 2 commits into from
May 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 0 additions & 16 deletions publicodes/core/source/AST/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ export const traverseASTNode: TraverseFunction<NodeKind> = (fn, node) => {
return traverseUnitéNode(fn, node)
case 'variations':
return traverseVariationNode(fn, node)
case 'variable temporelle':
return traverseVariableTemporelle(fn, node)
case 'replacementRule':
return traverseReplacementNode(fn, node)
default:
Expand Down Expand Up @@ -382,17 +380,3 @@ const traverseVariationNode: TraverseFunction<'variations'> = (fn, node) => ({
consequence: fn(consequence),
})),
})

const traverseVariableTemporelle: TraverseFunction<'variable temporelle'> = (
fn,
node
) => ({
...node,
explanation: {
period: {
end: node.explanation.period.end && fn(node.explanation.period.end),
start: node.explanation.period.start && fn(node.explanation.period.start),
},
value: fn(node.explanation.value),
},
})
5 changes: 0 additions & 5 deletions publicodes/core/source/AST/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,10 @@ import { SommeNode } from '../mecanisms/sum'
import { SynchronisationNode } from '../mecanisms/synchronisation'
import { TauxProgressifNode } from '../mecanisms/tauxProgressif'
import { UnitéNode } from '../mecanisms/unité'
import { VariableTemporelleNode } from '../mecanisms/variableTemporelle'
import { VariationNode } from '../mecanisms/variations'
import { ReferenceNode } from '../reference'
import { ReplacementRule } from '../replacement'
import { RuleNode } from '../rule'
import { Temporal } from '../temporal'

export type ConstantNode = {
type: 'boolean' | 'objet' | 'number' | 'string'
Expand Down Expand Up @@ -64,7 +62,6 @@ export type ASTNode = (
| SynchronisationNode
| TauxProgressifNode
| UnitéNode
| VariableTemporelleNode
| VariationNode
| ConstantNode
| ReplacementRule
Expand Down Expand Up @@ -109,12 +106,10 @@ export type Unit = {
}

// Idée : une évaluation est un n-uple : (value, unit, missingVariable, isApplicable)
// Une temporalEvaluation est une liste d'evaluation sur chaque période. : [(Evaluation, Period)]
type EvaluationDecoration<T extends Types> = {
nodeValue: Evaluation<T>
missingVariables: Record<string, number>
unit?: Unit
temporalValue?: Temporal<Evaluation>
}
export type Types = number | boolean | string | Record<string, unknown>
export type Evaluation<T extends Types = Types> = T | false | null
Expand Down
111 changes: 7 additions & 104 deletions publicodes/core/source/evaluation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,8 @@ import {
NodeKind,
} from './AST/types'
import { warning } from './error'
import { convertNodeToUnit, simplifyNodeUnit } from './nodeUnits'
import { convertNodeToUnit } from './nodeUnits'
import parse from './parse'
import {
concatTemporals,
liftTemporalNode,
mapTemporal,
pureTemporal,
Temporal,
temporalAverage,
zipTemporals,
} from './temporal'

export const collectNodeMissing = (
node: EvaluatedNode | ASTNode
Expand Down Expand Up @@ -75,37 +66,17 @@ export const evaluateArray: <NodeName extends NodeKind>(
node.explanation.map(evaluate),
node.name
)
const values = evaluatedNodes.map(({ nodeValue }) => nodeValue)
const nodeValue = values.some((value) => value === null)
? null
: values.reduce(reducer, start)

const temporalValues = concatTemporals(
evaluatedNodes.map(
({ temporalValue, nodeValue }) =>
temporalValue ?? pureTemporal(nodeValue)
)
)
const temporalValue = mapTemporal((values) => {
if (values.some((value) => value === null)) {
return null
}
return values.reduce(reducer, start)
}, temporalValues)

const baseEvaluation = {
return {
...node,
missingVariables: mergeAllMissing(evaluatedNodes),
explanation: evaluatedNodes,
...(evaluatedNodes[0] && { unit: evaluatedNodes[0].unit }),
}
if (temporalValue.length === 1) {
return {
...baseEvaluation,
nodeValue: temporalValue[0].value,
}
}

return {
...baseEvaluation,
temporalValue,
nodeValue: temporalAverage(temporalValue as any),
nodeValue,
}
}

Expand All @@ -132,71 +103,3 @@ export const parseObject = (objectShape, value, context) => {
})
)
}

export function evaluateObject<NodeName extends NodeKind>(
effet: (this: Engine, explanations: any) => any
) {
return function (node) {
const evaluations = Object.fromEntries(
Object.entries((node as any).explanation).map(([key, value]) => [
key,
this.evaluate(value as any),
])
)
const temporalExplanations = mapTemporal(
Object.fromEntries,
concatTemporals(
Object.entries(evaluations).map(([key, node]) =>
zipTemporals(pureTemporal(key), liftTemporalNode(node as ASTNode))
)
)
)
const temporalExplanation = mapTemporal((explanations) => {
const evaluation = effet.call(this, explanations)
return {
...evaluation,
explanation: {
...explanations,
...evaluation.explanation,
},
}
}, temporalExplanations)

const sameUnitTemporalExplanation: Temporal<
ASTNode & EvaluatedNode & { nodeValue: number }
> = convertNodesToSameUnit
.call(
this,
temporalExplanation.map((x) => x.value),
node.nodeKind
)
.map((node, i) => ({
...temporalExplanation[i],
value: simplifyNodeUnit(node),
}))

const temporalValue = mapTemporal(
({ nodeValue }) => nodeValue,
sameUnitTemporalExplanation
)
const nodeValue = temporalAverage(temporalValue)
const baseEvaluation = {
...node,
nodeValue,
unit: sameUnitTemporalExplanation[0].value.unit,
explanation: evaluations,
missingVariables: mergeAllMissing(Object.values(evaluations)),
}
if (sameUnitTemporalExplanation.length === 1) {
return {
...baseEvaluation,
explanation: (sameUnitTemporalExplanation[0] as any).value.explanation,
}
}
return {
...baseEvaluation,
temporalValue,
temporalExplanation,
}
} as EvaluationFunction<NodeName>
}
8 changes: 1 addition & 7 deletions publicodes/core/source/grammar.ne
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@

@{%
const {
string, date, variable, temporalNumericValue, binaryOperation,
unaryOperation, boolean, number, numberWithUnit, JSONObject
string, date, variable, binaryOperation, unaryOperation, boolean, number, numberWithUnit, JSONObject
} = require('./grammarFunctions')

const moo = require("moo");
Expand Down Expand Up @@ -61,11 +60,6 @@ main ->
NumericValue ->
AdditionSubstraction {% id %}
| Negation {% id %}
| TemporalNumericValue {% id %}

TemporalNumericValue ->
NumericValue %space %periodWord %space %date {% ([value,,word,,dateString]) => temporalNumericValue(value, word, date([dateString])) %}
| NumericValue %space %periodWord %colon Date {% ([value,,word,,date]) => temporalNumericValue(value, word, date) %}

NumericTerminal ->
Variable {% id %}
Expand Down
8 changes: 0 additions & 8 deletions publicodes/core/source/grammarFunctions.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* Those are postprocessor functions for the Nearley grammar.ne.
The advantage of putting them here is to get prettier's JS formatting, since Nealrey doesn't support it https://github.com/kach/nearley/issues/310 */
import { normalizeDateString } from './date'
import { parsePeriod } from './temporal'

export let binaryOperation = (operationType) => ([A, , operator, , B]) => ({
[operator]: {
Expand All @@ -17,13 +16,6 @@ export let unaryOperation = (operationType) => ([operator, , A]) => ({
},
})

export let temporalNumericValue = (variable, word, date) => ({
temporalValue: {
explanation: variable,
period: parsePeriod(word.value.slice(2), date),
},
})

export let variable = ([firstFragment, nextFragment], _, reject) => {
const fragments = [firstFragment, ...nextFragment].map(({ value }) => value)
if (!nextFragment.length && ['oui', 'non'].includes(firstFragment)) {
Expand Down
52 changes: 15 additions & 37 deletions publicodes/core/source/mecanisms/barème.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,6 @@ import { ASTNode } from '../AST/types'
import { defaultNode, mergeAllMissing } from '../evaluation'
import { registerEvaluationFunction } from '../evaluationFunctions'
import parse from '../parse'
import {
liftTemporal2,
liftTemporalNode,
mapTemporal,
temporalAverage,
} from '../temporal'
import { convertUnit, parseUnit } from '../units'
import {
evaluatePlafondUntilActiveTranche,
Expand Down Expand Up @@ -78,44 +72,28 @@ const evaluate: EvaluationFunction<'barème'> = function (node) {
const evaluate = this.evaluate.bind(this)
const assiette = this.evaluate(node.explanation.assiette)
const multiplicateur = this.evaluate(node.explanation.multiplicateur)
const temporalTranchesPlafond = liftTemporal2(
(assiette, multiplicateur) =>
evaluatePlafondUntilActiveTranche.call(this, {
parsedTranches: node.explanation.tranches,
assiette,
multiplicateur,
}),
liftTemporalNode(assiette as any),
liftTemporalNode(multiplicateur as any)
)
const temporalTranches = liftTemporal2(
(tranches, assiette) => evaluateBarème(tranches, assiette, evaluate),
temporalTranchesPlafond,
liftTemporalNode(assiette as any)
const tranches = evaluateBarème(
evaluatePlafondUntilActiveTranche.call(this, {
parsedTranches: node.explanation.tranches,
assiette,
multiplicateur,
}),
assiette,
evaluate
)
const temporalValue = mapTemporal(
(tranches) =>
tranches.reduce(
(value, { nodeValue }) =>
nodeValue == null ? null : value + nodeValue,
0
),
temporalTranches
const nodeValue = tranches.reduce(
(value, { nodeValue }) => (nodeValue == null ? null : value + nodeValue),
0
)

return {
...node,
nodeValue: temporalAverage(temporalValue),
...(temporalValue.length > 1
? {
temporalValue,
}
: { missingVariables: mergeAllMissing(temporalTranches[0].value) }),
nodeValue,
missingVariables: mergeAllMissing(tranches),
explanation: {
assiette,
multiplicateur,
...(temporalTranches.length > 1
? { temporalTranches }
: { tranches: temporalTranches[0].value }),
tranches,
},
unit: assiette.unit,
} as any
Expand Down
Loading