# `Dmn.Compiler.Checks`
[🔗](https://github.com/FeeJai/BDM/blob/dmn-v0.1.0/apps/dmn/lib/dmn/compiler/checks.ex#L1)

What the types of FEEL can say of a decision table before it runs (`Feel.Rules`).

The input entries of a table are unary tests, and the input of a column has the type the analysis gives its expression, so a rule is a
set of inputs and the questions about a table are about sets: does a pair of rules share an input, is a rule never reached, does the
table take every input. Each answer of `Feel.Rules` is proved, refuted with an input that shows it, or unknown, and only
what is shown is said:

| Code | Severity | When |
| ---- | -------- | ---- |
| `:overlapping_rules` | warning | two rules of a `UNIQUE` table that an input matches both of (the table is `null` with an error for it) |
| `:dead_rule` | warning | a rule of a `FIRST` table that the rules before it take every input of |
| `:incomplete_table` | info | a table with no default output that an input matches no rule of (the table is `null` for it) |
| `:table_not_checked` | info | a check ran out of time or memory, raised, or found mismatched model/prepared table dimensions |

The input that shows it is in the `details` as `input`, by the name `input 1`, `input 2`, … of the column. The questions are asked of a
table of at most 200 rules and 4,000 cells (rules times inputs), since the pairs of rules are the square of the first and each cell is
prepared for each question; a table of more is not asked.
Size skips and tables with no inputs produce a `:table_not_checked` diagnostic.
Individual proof questions can still be unknown; absence of a warning is not a proof.

The time is not bounded by the size of a table (100 rules of ranges and `not(…)` with 4 inputs took 38 s), so the questions about a
table are asked in a process that is ended at a deadline (`Feel.Worker`), and there is a deadline for all the tables of a compile
(`table_check_timeout` and `checks_timeout` of `Dmn.Limits`). A table that passed one is an info (`:table_not_checked`), and
says nothing of its rules.

The columns, rules and policy are those of the model; the types come from the prepared expression, in which a decision table is a
node whose span is the glue of the table (`Dmn.Compiler.Source`), and whose place in the model is its path.
Prepared wildcard entries use the column's effective `inputValues`; explicit entries use their own
tests. Source preparation retains the unit's named type definitions, including aliases and qualified
names, even when analysis has resolved or folded away an `instance of` reference. Proofs exclude null from column types, matching the table's null-input behavior.
A bound containing only null falls back to non-null `Any`. Questions concern these abstract
column domains, not reachability through upstream decisions or concrete host bindings.
A test that depends on model/local bindings, filter fields, dynamic lookup, extension calls or indirect calls is
passed as `:unknown`: possible inputs are the whole column and certain inputs are empty. Resolved
builtin aliases retain their binding provenance. Independent cells and rules can still prove facts;
model functions are not invoked for proof construction (DD-43).
Effective-source and column preparation run inside the same deadline/memory guard as the queries,
after the size checks. Reported witnesses are not universally revalidated against original entries.

# `budget`

```elixir
@type budget() :: %{
  table: pos_integer(),
  deadline: integer(),
  max_memory: pos_integer()
}
```

How long the questions may take: `table` milliseconds for each table, until `deadline` (in `System.monotonic_time(:millisecond)`) for
all of them, within `max_memory` bytes.

# `tables`

```elixir
@spec tables(
  Feel.Expression.t(),
  %{optional([term()]) =&gt; Dmn.Model.DecisionTable.t()},
  Dmn.Compiler.Source.finished(),
  String.t(),
  budget(),
  %{optional(String.t()) =&gt; Feel.Type.t()}
) :: [Dmn.Diagnostic.t()]
```

The diagnostics for the decision tables of an expression. `tables` are the tables the compiler made nodes of, by their path.
`types` must contain the named type definitions from the scope used to prepare the expression.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
