# `PtcRunner.Lisp.DataKeys`
[🔗](https://github.com/andreasronge/ptc_runner/blob/main/lib/ptc_runner/lisp/data_keys.ex#L1)

Static analysis to extract data keys accessed by a PTC-Lisp program.

Walks the Core AST to find all `{:data, key}` nodes, which represent
`data/xxx` access patterns in the source code.

This enables context optimization by loading only the datasets actually
needed by the program, reducing memory pressure during execution.

## Example

    iex> {:ok, ast} = PtcRunner.Lisp.Parser.parse("(count data/products)")
    iex> {:ok, core_ast} = PtcRunner.Lisp.Analyze.analyze(ast)
    iex> PtcRunner.Lisp.DataKeys.extract(core_ast)
    MapSet.new([:products])

# `extract`

```elixir
@spec extract(term()) :: MapSet.t()
```

Extracts all data keys accessed by a program.

Returns a MapSet of atoms/strings representing the keys accessed via `data/xxx`.

## Examples

    iex> {:ok, ast} = PtcRunner.Lisp.Parser.parse("(+ (count data/foo) (count data/bar))")
    iex> {:ok, core_ast} = PtcRunner.Lisp.Analyze.analyze(ast)
    iex> keys = PtcRunner.Lisp.DataKeys.extract(core_ast)
    iex> Enum.sort(keys)
    [:bar, :foo]

# `filter_context`

```elixir
@spec filter_context(term(), map()) :: map()
```

Filters a context map to only include keys accessed by the program.

Keys not present in the context are silently ignored (the program may
reference data that doesn't exist, which will be handled at runtime).

## Examples

    iex> {:ok, ast} = PtcRunner.Lisp.Parser.parse("(count data/products)")
    iex> {:ok, core_ast} = PtcRunner.Lisp.Analyze.analyze(ast)
    iex> ctx = %{"products" => [1,2,3], "orders" => [4,5,6], "question" => "test"}
    iex> PtcRunner.Lisp.DataKeys.filter_context(core_ast, ctx)
    %{"products" => [1,2,3], "question" => "test"}

---

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