# Equal values and distinct positions ## Intention I want to keep equal amounts of different charges when summing. Equal values of different entities collapse in a Set; the scenes repeat the case on two charges of 500 KZT. ## Incorrect form and why it stays silent ```text title="Incorrect form" sum(collect x: Money, c: Charge where amount(c, x)) ``` Set collapses equal amount values even when the charges are different. List keeps every substitution; the number of charges is counted over the entities themselves. ## Correct form ```law language "law.core" version "0.2"; package recipes.l.r11 version "0.1.0"; namespace "urn:recipe:l-calc:11"; entity Charge; relation amount(c: Charge, x: Money) { key(c); } relation total(x: Money); rule Total strict { when true; then total(sum(collect all x: Money, c: Charge where amount(c, x))); } ``` ## Frozen execution scene | Facts and choice | Question | Answer | |---|---|---| | 1. two equal positions, List | `truth(total(1000 KZT))` | `TRUE_ONLY` / `COMPUTED` | | 2. counterfactual: duplicate preservation removed | `truth(total(500 KZT))` | `TRUE_ONLY` / `COMPUTED` | | 3. number of amount values | `count(collect x: Money, c: Charge where amount(c, x))` | `1` / `COMPUTED` | | 4. number of charges | `count(collect c: Charge, x: Money where amount(c, x))` | `2` / `COMPUTED` | ```law test "two equal positions as list" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; } assert amount(entity_ref("urn:recipe:l-calc:11:a"), 500 KZT); assert amount(entity_ref("urn:recipe:l-calc:11:b"), 500 KZT); } evaluate truth(total(1000 KZT)); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` ```law test "duplicate preservation removed" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; } assert amount(entity_ref("urn:recipe:l-calc:11:a"), 500 KZT); assert amount(entity_ref("urn:recipe:l-calc:11:b"), 500 KZT); } evaluate truth(total(500 KZT)); expect truth_status == TRUE_ONLY; expect evaluation_status == COMPUTED; } ``` ```law test "count of sum values" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; } assert amount(entity_ref("urn:recipe:l-calc:11:a"), 500 KZT); assert amount(entity_ref("urn:recipe:l-calc:11:b"), 500 KZT); } evaluate count(collect x: Money, c: Charge where amount(c, x)); expect value == 1; expect evaluation_status == COMPUTED; } ``` ```law test "count of charges" { given { context { legal_time @2026-09-13; decision_time @2026-09-13T09:00:00+05:00; knowledge_time @2026-09-13T09:00:00+05:00; timezone "Asia/Almaty"; } assert amount(entity_ref("urn:recipe:l-calc:11:a"), 500 KZT); assert amount(entity_ref("urn:recipe:l-calc:11:b"), 500 KZT); } evaluate count(collect c: Charge, x: Money where amount(c, x)); expect value == 2; expect evaluation_status == COMPUTED; } ``` ## Counterfactual Mutation: `x: Money, c: Charge where amount(c, x)` → `x: Money where amount(c, x)`; expected `LDC-E1317`. Additional counterfactuals are shown as separate table rows. ## Boundary collect all does not remove extra substitutions over grounds — that is [Sum over items, not over grounds](/recipes/l-calc/count-items/). Choosing List for the sum and Set for entities does not replace a completeness check of input facts. ## Pitfall Two equal charges are one value but two positions: count them over the entities, not the amounts.