diff --git a/package-lock.json b/package-lock.json
index 56f58d5a5d374679929c8cf8141e3db7bb02008d..7428f0973bae37ea56396cf01344b01eb2055983 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,7 +14,7 @@
         "@auditors/core": "^0.1.7",
         "@fontsource/lato": "^4.3.0",
         "@fontsource/lora": "^4.3.0",
-        "@openfisca/ast": "^0.12.2",
+        "@openfisca/ast": "^0.13.0",
         "@sveltejs/adapter-node": "next",
         "@sveltejs/kit": "next",
         "@tailwindcss/forms": "^0.3.2",
@@ -1907,9 +1907,9 @@
       }
     },
     "node_modules/@openfisca/ast": {
-      "version": "0.12.2",
-      "resolved": "https://registry.npmjs.org/@openfisca/ast/-/ast-0.12.2.tgz",
-      "integrity": "sha512-ZuCd8e7LkejDR8VgSp2Xwjmp2H2ypU9aF2vogt278XuxSMCs/mseMhPxSWXf+eMaaYnatDTfrDHBUcKKOYbbCA==",
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/@openfisca/ast/-/ast-0.13.0.tgz",
+      "integrity": "sha512-zrpmi75kcngmmZj0hSy4TvYEcVlrf5LxpQtBXD6Lv+PH0HFyK+bMG75sbSOUb7Txnix8WDSP45NY6QlVHyXojw==",
       "dev": true,
       "dependencies": {
         "@auditors/core": "^0.1.11",
@@ -8235,9 +8235,9 @@
       }
     },
     "@openfisca/ast": {
-      "version": "0.12.2",
-      "resolved": "https://registry.npmjs.org/@openfisca/ast/-/ast-0.12.2.tgz",
-      "integrity": "sha512-ZuCd8e7LkejDR8VgSp2Xwjmp2H2ypU9aF2vogt278XuxSMCs/mseMhPxSWXf+eMaaYnatDTfrDHBUcKKOYbbCA==",
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/@openfisca/ast/-/ast-0.13.0.tgz",
+      "integrity": "sha512-zrpmi75kcngmmZj0hSy4TvYEcVlrf5LxpQtBXD6Lv+PH0HFyK+bMG75sbSOUb7Txnix8WDSP45NY6QlVHyXojw==",
       "dev": true,
       "requires": {
         "@auditors/core": "^0.1.11",
diff --git a/package.json b/package.json
index 08c8d1b8ccc3ecc688e96fe4543a75067d403542..e51786f25fe795e164b5c4cd46bff9c72836c468 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "@auditors/core": "^0.1.7",
     "@fontsource/lato": "^4.3.0",
     "@fontsource/lora": "^4.3.0",
-    "@openfisca/ast": "^0.12.2",
+    "@openfisca/ast": "^0.13.0",
     "@sveltejs/adapter-node": "next",
     "@sveltejs/kit": "next",
     "@tailwindcss/forms": "^0.3.2",
diff --git a/src/lib/components/latchkeys/Arrow.svelte b/src/lib/components/latchkeys/Arrow.svelte
index 4105a56c2069eb0129cbdc58fc78637f38969976..0e55561a2eb4e7f9390a54f22b3d27acb9a30745 100644
--- a/src/lib/components/latchkeys/Arrow.svelte
+++ b/src/lib/components/latchkeys/Arrow.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import type { Waterfall } from "@openfisca/ast"
   import { getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
@@ -50,8 +51,7 @@
   // const showColoredRects = getContext("showColoredRects") as Writable<boolean>
   const testCaseIndex = getContext("testCaseIndex") as Writable<number>
   const verticalLineStrokeWidth = 2
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
 
   $: aggregate = item.aggregate
 
@@ -88,6 +88,8 @@
     aggregate !== undefined &&
     (aggregate === leaf || aggregate.values.some(([x0]) => x0 !== 0))
 
+  $: rootDecompositionName = $waterfall.root
+
   $: triangleHalfHeight = (width * chevronHeightWidthRatio) / 2
 
   $: x = x0 < x1 ? x0 : x1
diff --git a/src/lib/components/latchkeys/AxisY.svelte b/src/lib/components/latchkeys/AxisY.svelte
index 3b49443d710a3ff051a38dbbaf083e9de8859ef0..ad14dc849df76e004e13c65c549dfb1b14d93a13 100644
--- a/src/lib/components/latchkeys/AxisY.svelte
+++ b/src/lib/components/latchkeys/AxisY.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import type { Waterfall } from "@openfisca/ast"
   import { createEventDispatcher, getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
@@ -19,8 +20,9 @@
   ) as Writable<DecompositionByName[]>
   const dispatch = createEventDispatcher()
   const testCaseIndex = getContext("testCaseIndex") as Writable<number>
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
+
+  $: rootDecompositionName = $waterfall.root
 
   $: yHalfBandwidth = $yScale.bandwidth() / 2
 
diff --git a/src/lib/components/latchkeys/Latchkey.svelte b/src/lib/components/latchkeys/Latchkey.svelte
index dd3d377c86b3fc08f37558574d4e2709bc62ff79..a24fdc0e53aaa23d174c506a2fbc91d4f1e4ad59 100644
--- a/src/lib/components/latchkeys/Latchkey.svelte
+++ b/src/lib/components/latchkeys/Latchkey.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import type { Waterfall } from "@openfisca/ast"
   import { scaleBand } from "d3-scale"
   import { getContext } from "svelte"
   import type { Writable } from "svelte/store"
@@ -21,12 +22,13 @@
   ) as Writable<DecompositionByName[]>
   const showNulls = getContext("showNulls") as Writable<boolean>
   const testCaseIndex = getContext("testCaseIndex") as Writable<number>
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
 
   // const showColoredRects = writable(false)
   // setContext("showColoredRects", showColoredRects)
 
+  $: rootDecompositionName = $waterfall.root
+
   $: data = aggregateDecomposition(
     $decompositionByNameArray[$testCaseIndex],
     rootDecompositionName,
diff --git a/src/lib/components/parameters/ValueAtInstantEdit.svelte b/src/lib/components/parameters/ValueAtInstantEdit.svelte
index 1c869c62dd9082e85c285dee08cee7a33612bd01..23b4640baac69c9047067f46993a32b81401867a 100644
--- a/src/lib/components/parameters/ValueAtInstantEdit.svelte
+++ b/src/lib/components/parameters/ValueAtInstantEdit.svelte
@@ -43,7 +43,7 @@
   }
 
   function changeUnit({ target }: Event) {
-    const { value } = target as HTMLInputElement
+    const { value } = target as HTMLSelectElement
     ;[valueAtInstant, errors] = auditEditedAttribute(
       laxAudit,
       valueAtInstant === "expected" ? { value: null } : valueAtInstant,
diff --git a/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte b/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
index b010c5348f4c1984d8d45a54bc6af516b1dcc172..1cdbf6267d2f2a79c2c038e27722ae79b685d52b 100644
--- a/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
+++ b/src/lib/components/scholar_waterfalls/ScholarWaterfall.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import type { Waterfall } from "@openfisca/ast"
   import { createEventDispatcher, getContext } from "svelte"
   import type { Writable } from "svelte/store"
 
@@ -38,14 +39,16 @@
   })
   const showNulls = getContext("showNulls") as Writable<boolean>
   const testCaseIndex = getContext("testCaseIndex") as Writable<number>
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
   let waterfallWidth = 100
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+
+  $: rootDecompositionName = $waterfall.root
 
   $: decompositionEvaluationAndDepthTriples = [
     ...walkVisibleEvaluations(
       decompositionByName,
       evaluationByName,
+      $waterfall.name,
       rootDecompositionName,
       $showNulls,
     ),
@@ -126,6 +129,7 @@
   export function* walkVisibleEvaluations(
     decompositionByName: DecompositionByName,
     evaluationByName: EvaluationByName,
+    waterfallName: string,
     name: string,
     showNulls: boolean,
     depth: number = 0,
@@ -138,8 +142,25 @@
     if (evaluation === undefined) {
       return
     }
-    const showNode =
-      (showNulls && !decomposition.hidden) || !evaluation.deltaIs0Array
+
+    let hidden = decomposition.hidden
+    // for (const options of decomposition.options ?? []) {
+    //   if (
+    //     options.then?.hidden !== undefined &&
+    //     (options.waterfall === undefined ||
+    //       options.waterfall.includes(waterfallName))
+    //   ) {
+    //     hidden = options.then.hidden ?? undefined
+    //   } else if (
+    //     options.else?.hidden !== undefined &&
+    //     options.waterfall !== undefined &&
+    //     !options.waterfall.includes(waterfallName)
+    //   ) {
+    //     hidden = options.else.hidden ?? undefined
+    //   }
+    // }
+
+    const showNode = (showNulls && !hidden) || !evaluation.deltaIs0Array
     if (showNode) {
       let childrenDepth = depth
       if (!decomposition.trunk) {
@@ -151,6 +172,7 @@
           yield* walkVisibleEvaluations(
             decompositionByName,
             evaluationByName,
+            waterfallName,
             childName,
             showNulls,
             childrenDepth,
diff --git a/src/lib/components/test_cases/TestCaseView.svelte b/src/lib/components/test_cases/TestCaseView.svelte
index cfce09960ed1e261d469029325f26c65b08b84f6..a7928ab5e05f2514786e6cfa4b34140f555eec35 100644
--- a/src/lib/components/test_cases/TestCaseView.svelte
+++ b/src/lib/components/test_cases/TestCaseView.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { EntityByKey, Variable } from "@openfisca/ast"
+  import type { EntityByKey, Variable, Waterfall } from "@openfisca/ast"
   import { createEventDispatcher, getContext, tick } from "svelte"
   import type { Writable } from "svelte/store"
 
@@ -79,13 +79,7 @@
   )
   let variableSummaryByName: { [name: string]: Variable } | undefined =
     undefined
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
-  const firstDecompositionName = walkDecompositionsCoreName(
-    $session.decompositionCoreByName,
-    rootDecompositionName,
-    true,
-  ).next().value as string
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
 
   $: familySituation = situation[familyEntity.key_plural]
 
@@ -98,6 +92,15 @@
   $: evaluationByName =
     evaluationByNameArrayByCalculationName[calculationName][situationIndex]
 
+  $: rootDecompositionName = $waterfall.root
+
+  $: firstDecompositionName = walkDecompositionsCoreName(
+    $session.decompositionCoreByName,
+    $waterfall.name,
+    rootDecompositionName,
+    true,
+  ).next().value[0] as string
+
   $: personSituation = situation[personEntity.key_plural]
 
   $: adultsCount = Object.keys(personSituation).length - childrenCount
@@ -472,15 +475,15 @@
             ? undefined
             : evaluationByNameArrayByCalculationName.amendment[situationIndex][
                 rootDecompositionName
-              ].deltaAtVectorIndex ?? 0}
+              ]?.deltaAtVectorIndex ?? 0}
           billValue={$billName === undefined
             ? undefined
             : evaluationByNameArrayByCalculationName.bill[situationIndex][
                 rootDecompositionName
-              ].deltaAtVectorIndex ?? 0}
+              ]?.deltaAtVectorIndex ?? 0}
           lawValue={evaluationByNameArrayByCalculationName.law[situationIndex][
             rootDecompositionName
-          ].deltaAtVectorIndex ?? 0}
+          ]?.deltaAtVectorIndex ?? 0}
         />
       </p>
     </div>
@@ -501,15 +504,15 @@
             ? undefined
             : evaluationByNameArrayByCalculationName.amendment[situationIndex][
                 firstDecompositionName
-              ].deltaAtVectorIndex ?? 0}
+              ]?.deltaAtVectorIndex ?? 0}
           billValue={$billName === undefined
             ? undefined
             : evaluationByNameArrayByCalculationName.bill[situationIndex][
                 firstDecompositionName
-              ].deltaAtVectorIndex ?? 0}
+              ]?.deltaAtVectorIndex ?? 0}
           lawValue={evaluationByNameArrayByCalculationName.law[situationIndex][
             firstDecompositionName
-          ].deltaAtVectorIndex ?? 0}
+          ]?.deltaAtVectorIndex ?? 0}
         />
       </p>
     </div>
@@ -532,24 +535,24 @@
             ? undefined
             : (evaluationByNameArrayByCalculationName.amendment[situationIndex][
                 rootDecompositionName
-              ].deltaAtVectorIndex ?? 0) -
+              ]?.deltaAtVectorIndex ?? 0) -
               (evaluationByNameArrayByCalculationName.amendment[situationIndex][
                 firstDecompositionName
-              ].deltaAtVectorIndex ?? 0)}
+              ]?.deltaAtVectorIndex ?? 0)}
           billValue={$billName === undefined
             ? undefined
             : (evaluationByNameArrayByCalculationName.bill[situationIndex][
                 rootDecompositionName
-              ].deltaAtVectorIndex ?? 0) -
+              ]?.deltaAtVectorIndex ?? 0) -
               (evaluationByNameArrayByCalculationName.bill[situationIndex][
                 firstDecompositionName
-              ].deltaAtVectorIndex ?? 0)}
+              ]?.deltaAtVectorIndex ?? 0)}
           lawValue={(evaluationByNameArrayByCalculationName.law[situationIndex][
             rootDecompositionName
-          ].deltaAtVectorIndex ?? 0) -
+          ]?.deltaAtVectorIndex ?? 0) -
             (evaluationByNameArrayByCalculationName.law[situationIndex][
               firstDecompositionName
-            ].deltaAtVectorIndex ?? 0)}
+            ]?.deltaAtVectorIndex ?? 0)}
         />
       </p>
     </div>
diff --git a/src/lib/components/variables/VariableReferredInputsPane.svelte b/src/lib/components/variables/VariableReferredInputsPane.svelte
index 48c4104268b0b06ae95f76012b46ff3c37da8191..2f3104cee4c7e9beb15fa42d46cd429e6e119120 100644
--- a/src/lib/components/variables/VariableReferredInputsPane.svelte
+++ b/src/lib/components/variables/VariableReferredInputsPane.svelte
@@ -1,5 +1,7 @@
 <script lang="ts">
-  import type { Variable } from "@openfisca/ast"
+  import type { Variable, Waterfall } from "@openfisca/ast"
+  import { getContext } from "svelte"
+  import type { Writable } from "svelte/store"
 
   import { browser } from "$app/env"
   import VariableReferredInputs from "./VariableReferredInputs.svelte"
@@ -12,6 +14,7 @@
 
   let inputs: Variable[] | undefined = undefined
   let variable: Variable | undefined = undefined
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
 
   $: browser && retrieveVariable(name)
 
@@ -36,7 +39,9 @@
     name: string,
     date: string,
   ): Promise<void> {
-    const url = `/variables/${name}/inputs/${date}.json?filter_decomposition=true`
+    const url = `/variables/${name}/inputs/${date}.json?filter_decomposition=true&waterfall=${encodeURIComponent(
+      $waterfall.name,
+    )}`
     const res = await fetch(url)
     if (res.ok) {
       inputs = await res.json()
diff --git a/src/lib/components/waterfalls/Waterfall.svelte b/src/lib/components/waterfalls/Waterfall.svelte
index a144d6ead1e556d2f54366567752c266681017dd..92e6d7395928d3277f61987b76cfbfc70f13ba7d 100644
--- a/src/lib/components/waterfalls/Waterfall.svelte
+++ b/src/lib/components/waterfalls/Waterfall.svelte
@@ -1,4 +1,5 @@
 <script lang="ts">
+  import type { Waterfall } from "@openfisca/ast"
   import { scaleBand } from "d3-scale"
   import { getContext } from "svelte"
   import type { Writable } from "svelte/store"
@@ -18,8 +19,9 @@
   ) as Writable<DecompositionByName[]>
   const showNulls = getContext("showNulls") as Writable<boolean>
   const testCaseIndex = getContext("testCaseIndex") as Writable<number>
-  const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
+
+  $: rootDecompositionName = $waterfall.root
 
   $: data = [
     ...walkDecompositions(
diff --git a/src/lib/decompositions.ts b/src/lib/decompositions.ts
index 213e52c769d3d706ff33338a69449352bf4b8948..2480f745f49e777e26bc8021e323c1283a2d962d 100644
--- a/src/lib/decompositions.ts
+++ b/src/lib/decompositions.ts
@@ -5,7 +5,7 @@ export type {
 import type {
   Decomposition as DecompositionCore,
   DecompositionByName as DecompositionCoreByName,
-  DecompositionReference,
+  DecompositionOptions,
 } from "@openfisca/ast"
 
 export type CalculationName = "amendment" | "bill" | "law"
@@ -21,6 +21,7 @@ export interface Decomposition {
   negate?: boolean
   obsolete?: boolean
   open?: boolean
+  options?: DecompositionOptions[]
   parentName?: string
   previousChildStack?: string[]
   trunk: boolean
@@ -54,6 +55,7 @@ export const calculationNames: CalculationName[] = ["law", "bill", "amendment"]
 
 export function decompositionByNameFromCore(
   decompositionCoreByName: DecompositionCoreByName,
+  waterfallName: string,
   name: string,
   parentName: string | undefined = undefined,
   index = 0,
@@ -72,8 +74,24 @@ export function decompositionByNameFromCore(
     console.error(`Error: Variable "${name}" is missing from decomposition.`)
     return undefined
   }
+
+  let hidden = decompositionCore.hidden
+  for (const options of decompositionCore.options ?? []) {
+    if (options.waterfall === undefined) {
+      continue
+    }
+    if (
+      options.waterfall.includes(waterfallName) &&
+      options.then?.hidden !== undefined
+    ) {
+      hidden = options.then.hidden ?? undefined
+    } else if (options.else?.hidden !== undefined) {
+      hidden = options.else.hidden ?? undefined
+    }
+  }
+
   const decomposition: Decomposition = {
-    hidden: decompositionCore.hidden,
+    hidden,
     index,
     involve: decompositionCore.involve,
     label: decompositionCore.label,
@@ -81,6 +99,7 @@ export function decompositionByNameFromCore(
     name,
     negate,
     obsolete: decompositionCore.obsolete,
+    options: decompositionCore.options,
     trunk,
     ux_name: decompositionCore.ux_name,
     virtual: decompositionCore.virtual,
@@ -89,10 +108,23 @@ export function decompositionByNameFromCore(
   if (parentName !== undefined) {
     decomposition.parentName = parentName
   }
-  if (decompositionCore.children !== undefined) {
-    decomposition.childrenName = decompositionCore.children.map(
-      ({ name }) => name,
-    )
+
+  let children = decompositionCore.children
+  for (const options of decompositionCore.options ?? []) {
+    if (options.waterfall === undefined) {
+      continue
+    }
+    if (
+      options.waterfall.includes(waterfallName) &&
+      options.then?.children !== undefined
+    ) {
+      children = options.then.children ?? undefined
+    } else if (options.else?.children !== undefined) {
+      children = options.else.children ?? undefined
+    }
+  }
+  if (children !== undefined) {
+    decomposition.childrenName = children.map(({ name }) => name)
     let ancestor: Decomposition | undefined = undefined
     let depth = 0
     for (const ancestorName of iterDecompositionAncestorsName(
@@ -115,12 +147,10 @@ export function decompositionByNameFromCore(
     if (depth < 1) {
       decomposition.open = true
     }
-    for (const [
-      childIndex,
-      childReference,
-    ] of decompositionCore.children.entries()) {
+    for (const [childIndex, childReference] of children.entries()) {
       decompositionByNameFromCore(
         decompositionCoreByName,
+        waterfallName,
         childReference.name,
         name,
         childIndex,
@@ -182,9 +212,12 @@ export function updateEvaluations(
   name: string,
   vectorIndex: number,
   vectorLength: number,
-  newEvaluationByName: EvaluationByName = {},
+  newEvaluationByName: EvaluationByName | undefined = undefined,
   valuesPrevious = undefined,
 ): EvaluationByName {
+  if (newEvaluationByName === undefined) {
+    newEvaluationByName = { ...evaluationByName }
+  }
   const decomposition = decompositionByName[name]
   if (decomposition === undefined) {
     return newEvaluationByName
@@ -206,6 +239,11 @@ export function updateEvaluations(
         childValuesPrevious,
       )
       const childEvaluation = newEvaluationByName[childName]
+      if (childEvaluation === undefined) {
+        console.error(
+          `Undefined evaluation for child "${childName}" of "${name}"`,
+        )
+      }
       childValuesPrevious = childEvaluation.values.map(
         (itemValue) => itemValue[1],
       )
@@ -322,6 +360,7 @@ export function* walkDecompositions(
 
 export function* walkDecompositionsCore(
   decompositionCoreByName: DecompositionCoreByName,
+  waterfallName: string,
   name: string,
   depthFirst: boolean,
 ): Generator<[string, DecompositionCore], void, unknown> {
@@ -332,15 +371,32 @@ export function* walkDecompositionsCore(
   if (!depthFirst) {
     yield [name, decompositionCore]
   }
-  if (decompositionCore.children !== undefined) {
-    for (const childReference of decompositionCore.children) {
+
+  let children = decompositionCore.children
+  for (const options of decompositionCore.options ?? []) {
+    if (options.waterfall === undefined) {
+      continue
+    }
+    if (
+      options.waterfall.includes(waterfallName) &&
+      options.then?.children !== undefined
+    ) {
+      children = options.then.children ?? undefined
+    } else if (options.else?.children !== undefined) {
+      children = options.else.children ?? undefined
+    }
+  }
+  if (children !== undefined) {
+    for (const childReference of children) {
       yield* walkDecompositionsCore(
         decompositionCoreByName,
+        waterfallName,
         childReference.name,
         depthFirst,
       )
     }
   }
+
   if (depthFirst) {
     yield [name, decompositionCore]
   }
@@ -348,26 +404,16 @@ export function* walkDecompositionsCore(
 
 export function* walkDecompositionsCoreName(
   decompositionCoreByName: DecompositionCoreByName,
+  waterfallName: string,
   name: string,
   depthFirst: boolean,
 ): Generator<string, void, unknown> {
-  const decompositionCore = decompositionCoreByName[name]
-  if (decompositionCore === undefined) {
-    return
-  }
-  if (!depthFirst) {
-    yield name
-  }
-  if (decompositionCore.children !== undefined) {
-    for (const childReference of decompositionCore.children) {
-      yield* walkDecompositionsCoreName(
-        decompositionCoreByName,
-        childReference.name,
-        depthFirst,
-      )
-    }
-  }
-  if (depthFirst) {
-    yield name
+  for (const [decompositionName, _decompositionCore] of walkDecompositionsCore(
+    decompositionCoreByName,
+    waterfallName,
+    name,
+    depthFirst,
+  )) {
+    yield decompositionName
   }
 }
diff --git a/src/lib/server/decompositions.ts b/src/lib/server/decompositions.ts
index 414f03ac848ee61f7cc78fdd21e7eb355939f063..a74f9a9220a1b9c62451d370febb9369fb3850ba 100644
--- a/src/lib/server/decompositions.ts
+++ b/src/lib/server/decompositions.ts
@@ -45,7 +45,11 @@ export const waterfalls = validWaterfalls
 
 for (const waterfall of waterfalls) {
   assert.notStrictEqual(
-    decompositionByNameFromCore(decompositionCoreByName, waterfall.root),
+    decompositionByNameFromCore(
+      decompositionCoreByName,
+      waterfall.name,
+      waterfall.root,
+    ),
     undefined,
   )
 }
diff --git a/src/routes/__layout.svelte b/src/routes/__layout.svelte
index bbcf6be1398ba77d6136bf51b4217ac00c53b6b1..a8745b43c9db2a513c5d6f73dd5e4387a81ec605 100644
--- a/src/routes/__layout.svelte
+++ b/src/routes/__layout.svelte
@@ -1,7 +1,7 @@
 <script lang="ts">
   import "../app.css"
 
-  import type { EntityByKey } from "@openfisca/ast"
+  import type { EntityByKey, Waterfall } from "@openfisca/ast"
   import { setContext } from "svelte"
   import type { Writable } from "svelte/store"
   import { writable } from "svelte/store"
@@ -10,7 +10,11 @@
   import { browser } from "$app/env"
   import { page, session } from "$app/stores"
   import NavBar from "$lib/components/NavBar.svelte"
-  import type { CalculationName, EvaluationByName } from "$lib/decompositions"
+  import type {
+    CalculationName,
+    DecompositionCoreByName,
+    EvaluationByName,
+  } from "$lib/decompositions"
   import {
     calculationNames,
     decompositionByNameFromCore,
@@ -28,6 +32,11 @@
   const calculationName: Writable<CalculationName> = writable("law")
   setContext("calculationName", calculationName)
 
+  const calculationTokenByName: Writable<
+    { [name in CalculationName]?: string }
+  > = writable({})
+  setContext("calculationTokenByName", calculationTokenByName)
+
   const entityByKey = $session.entityByKey as EntityByKey
 
   const vectorIndexes: Writable<number[]> = writable(
@@ -39,11 +48,15 @@
   setContext("vectorLength", vectorLength)
 
   const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
+  let waterfall = writable(waterfalls[0])
+  setContext("waterfall", waterfall)
+  let waterfallName = $waterfall.name // Used to track change of waterfall.
+
   const decompositionByName = writable(
     decompositionByNameFromCore(
       $session.decompositionCoreByName,
-      rootDecompositionName,
+      $waterfall.name,
+      $waterfall.root,
     ),
   )
   setContext("decompositionByName", decompositionByName)
@@ -60,7 +73,7 @@
             updateEvaluations(
               $decompositionByName,
               {},
-              rootDecompositionName,
+              $waterfall.root,
               $vectorIndexes[situationIndex],
               $vectorLength,
             ),
@@ -82,19 +95,10 @@
 
   // Note: Duplicates are removed from nonVirtualDecompositionsName, because a variable name
   // may appear more than once in decomposition.
-  const nonVirtualDecompositionsName = [
-    ...new Set(
-      [
-        ...walkDecompositionsCore(
-          $session.decompositionCoreByName,
-          rootDecompositionName,
-          true,
-        ),
-      ]
-        .filter(([name, decomposition]) => !decomposition.virtual)
-        .map(([name, _decomposition]) => name),
-    ),
-  ]
+  const nonVirtualDecompositionsName = computeNonVirtualDecompositionsName(
+    $session.decompositionCoreByName,
+    waterfalls,
+  )
   setContext("nonVirtualDecompositionsName", nonVirtualDecompositionsName)
 
   const reform = writable({})
@@ -109,11 +113,6 @@
   const testCases = writable($session.testCases as Situation[])
   setContext("testCases", testCases)
 
-  const calculationTokenByName: Writable<
-    { [name in CalculationName]?: string }
-  > = writable({})
-  setContext("calculationTokenByName", calculationTokenByName)
-
   let variableValuesByName: { [name: string]: VariableValues } = {}
 
   const webSocketByName: Writable<WebSocketByName | undefined> =
@@ -126,6 +125,34 @@
   const year = writable(2021)
   setContext("year", year)
 
+  $: rootDecompositionName = $waterfall.root
+
+  $: if ($waterfall.name !== waterfallName) {
+    // Another waterfall has been selected.
+    waterfallName = $waterfall.name
+    $decompositionByName = decompositionByNameFromCore(
+      $session.decompositionCoreByName,
+      $waterfall.name,
+      $waterfall.root,
+    )
+    $evaluationByNameArrayByCalculationName = Object.fromEntries(
+      Object.entries($evaluationByNameArrayByCalculationName).map(
+        ([calculationName, evaluationByNameArray]) => [
+          calculationName,
+          evaluationByNameArray.map((evaluationByName, situationIndex) =>
+            updateEvaluations(
+              $decompositionByName,
+              evaluationByName,
+              $waterfall.root,
+              $vectorIndexes[situationIndex],
+              $vectorLength,
+            ),
+          ),
+        ],
+      ),
+    )
+  }
+
   if (browser && matomoConfig !== undefined) {
     function matomo(id, url) {
       // @ts-expect-error
@@ -186,6 +213,29 @@
     _paq.push(["trackPageView"])
   }
 
+  function computeNonVirtualDecompositionsName(
+    decompositionCoreByName: DecompositionCoreByName,
+    waterfalls: Waterfall[],
+  ): string[] {
+    const nonVirtualDecompositionsName: string[] = []
+    for (const { name: waterfallName, root } of waterfalls) {
+      for (const [name, decomposition] of walkDecompositionsCore(
+        decompositionCoreByName,
+        waterfallName,
+        root,
+        true,
+      )) {
+        if (
+          !decomposition.virtual &&
+          !nonVirtualDecompositionsName.includes(name)
+        ) {
+          nonVirtualDecompositionsName.push(name)
+        }
+      }
+    }
+    return nonVirtualDecompositionsName
+  }
+
   function extractInputInstantsFromTestCases(testCases: Situation[]): {
     [name: string]: Set<string>
   } {
@@ -323,7 +373,9 @@
                             ...evaluationByName,
                             [result.name]: {
                               ...evaluationByName[result.name],
-                              delta: $decompositionByName[result.name].negate
+                              delta: $session.decompositionCoreByName[
+                                result.name
+                              ].negate
                                 ? sum.map((sumItem) => -sumItem)
                                 : sum,
                               fromOpenFisca: true,
diff --git a/src/routes/index.svelte b/src/routes/index.svelte
index 664b8c67393aa32b94203de2586e2f20fe0a0c1b..8fcaa2d0915b95b964bdfb68737f372732d9ae1b 100644
--- a/src/routes/index.svelte
+++ b/src/routes/index.svelte
@@ -1,5 +1,5 @@
 <script lang="ts">
-  import type { EntityByKey, GroupEntity } from "@openfisca/ast"
+  import type { EntityByKey, GroupEntity, Waterfall } from "@openfisca/ast"
   import { getRolePersonsIdKey } from "@openfisca/ast"
   import { getContext, setContext } from "svelte"
   import type { Writable } from "svelte/store"
@@ -97,8 +97,8 @@
   ) as Writable<{ [name in CalculationName]?: string }>
   const vectorIndexes = getContext("vectorIndexes") as Writable<number[]>
   const vectorLength = getContext("vectorLength") as Writable<number>
+  const waterfall = getContext("waterfall") as Writable<Waterfall>
   const waterfalls = $session.waterfalls
-  const rootDecompositionName = waterfalls[0].root
   const webSocketByName = getContext("webSocketByName") as Writable<
     WebSocketByName | undefined
   >
@@ -109,9 +109,12 @@
 
   $: query = ensureValidQuery($page.query)
 
+  $: rootDecompositionName = $waterfall.root
+
   $: $action = query.action
 
   $: if ($simulationRequested) {
+    console.log("Simulation requested")
     $simulationRequested = false
     submit()
   }
@@ -202,6 +205,11 @@
     }
   }
 
+  function changeWaterfall({ target }: Event) {
+    const { value } = target as HTMLSelectElement
+    $waterfall = waterfalls.find(({ name }) => name === value)
+  }
+
   function closeEditionPane() {
     if (editionMode.mode === "tutorial") {
       editionMode = null
@@ -333,6 +341,7 @@
   }
 
   function submit() {
+    console.log("submit called")
     // Aggregate every situations into a single one without calculated variables.
     const aggregatedSituation: SituationWithAxes = {}
     const entities = Object.values($session.entityByKey as EntityByKey)
@@ -679,8 +688,7 @@
   <div class="w-full {editionMode !== null ? 'hidden md:block' : ''}">
     <div class="mx-1 my-2 px-4">
       <div class="flex justify-between">
-        <!--
-        <label
+        <!-- <label
           ><input bind:checked={$adaptAmountsScale} type="checkbox" />
           <span class="hidden text-xs lg:inline text-gray-600">
             Échelle identique pour tous les cas types
@@ -688,8 +696,7 @@
           <span class="lg:hidden text-xs inline text-gray-600 leading-none ">
             Échelle unique
           </span></label
-        >
-        -->
+        > -->
         <select
           class=" rounded border-1 text-xs "
           required
@@ -700,6 +707,18 @@
           {/each}
         </select>
 
+        <select
+          class=" rounded border-1 text-xs "
+          on:blur={changeWaterfall}
+          on:change={changeWaterfall}
+          required
+          value={$waterfall.name}
+        >
+          {#each waterfalls as { label, name }}
+            <option value={name}>{label}</option>
+          {/each}
+        </select>
+
         <div class="flex">
           <button
             class="bg-gray-200 text-gray-900 shadow-md hover:bg-gray-400 px-5 mr-2 rounded p-2 uppercase text-sm"
diff --git a/src/routes/variables/[variable]/inputs/[date].json.ts b/src/routes/variables/[variable]/inputs/[date].json.ts
index 1a9330fce140ed4938ca9ad94c6d20e0d2fac940..b4a31cf70d1a88b901b241b855ac4333eca64d1b 100644
--- a/src/routes/variables/[variable]/inputs/[date].json.ts
+++ b/src/routes/variables/[variable]/inputs/[date].json.ts
@@ -2,6 +2,8 @@ import {
   Audit,
   auditArray,
   auditFunction,
+  auditOptions,
+  auditRequire,
   auditSetNullish,
   auditStringToBoolean,
   auditTrimString,
@@ -19,7 +21,6 @@ import { decompositionCoreByName, waterfalls } from "$lib/server/decompositions"
 import { iterVariableInputVariables } from "$lib/server/variables"
 
 const { jsonDir } = config
-const rootDecompositionName = waterfalls[0].root
 
 function auditVariableInputsQuery(
   audit: Audit,
@@ -55,6 +56,29 @@ function auditVariableInputsQuery(
     auditFunction((value) => value[value.length - 1]),
     auditSetNullish(false),
   )
+  audit.attribute(
+    data,
+    "waterfall",
+    true,
+    errors,
+    remainingKeys,
+    auditOptions(waterfalls.map(({ name }) => name)),
+  )
+
+  if (
+    errors.filter_decomposition === undefined &&
+    data.filter_decomposition &&
+    errors.waterfall === undefined
+  ) {
+    audit.attribute(
+      data,
+      "waterfall",
+      true,
+      errors,
+      remainingKeys,
+      auditRequire,
+    )
+  }
 
   return audit.reduceRemaining(data, errors, remainingKeys, auditSetNullish({}))
 }
@@ -86,8 +110,12 @@ export const get: RequestHandler = async ({
       },
     }
   }
-  const { filter_decomposition: filterDecomposition } = query as {
+  const {
+    filter_decomposition: filterDecomposition,
+    waterfall: waterfallName,
+  } = query as {
     filter_decomposition: boolean
+    waterfall?: string
   }
 
   const { date, variable: name } = params
@@ -103,10 +131,12 @@ export const get: RequestHandler = async ({
 
   let ignoreVariablesName: Set<string>
   if (filterDecomposition) {
+    const waterfall = waterfalls.find(({ name }) => name === waterfallName)
     ignoreVariablesName = new Set(
       walkDecompositionsCoreName(
         decompositionCoreByName,
-        rootDecompositionName,
+        waterfall.name,
+        waterfall.root,
         false,
       ),
     )