# `MontyCad.Library`
[🔗](https://github.com/d-led/ex.monty.cad/blob/main/lib/monty_cad/library.ex#L1)

A graph memory in the form a Monty run loads.

Monty's pretrained memory is one file of JSON lines, gzipped, one record per
object and input channel:

    {"object_id": "bracket", "input_channel": "patch",
     "positions": [[x, y, z], …], "features": {"hsv": [[h, s, v], …], …}}

That is the whole format — `Monty.Studio.Memory` in the studio reads it back
into a `GraphMemory` and matches with it. So a part learned from CAD writes the
same file a training episode writes, and a run does not know the difference.

Records are written with `lm_index` `0`: a library built from one part is one
learning module's memory, and a heterarchy's is several libraries.

# `t`

```elixir
@type t() :: %MontyCad.Library{
  channel: String.t(),
  features: %{optional(String.t()) =&gt; [term()]},
  object_id: String.t(),
  positions: [[float()]]
}
```

# `feature_names`

```elixir
@spec feature_names(t()) :: [String.t()]
```

The feature names the library holds.

# `new`

```elixir
@spec new(String.t(), [[float()]], [%{optional(String.t()) =&gt; term()}], keyword()) ::
  {:ok, t()} | {:error, Quiddity.Error.t()}
```

A library from nodes: their locations and their features, one column a feature.

`features` is what `MontyCad.Percept.node_features/1` answered per node, so
this is a transpose with the shape of the file to write: every feature becomes
a column of the same length as `positions`.

# `records`

```elixir
@spec records(t(), keyword()) :: [map()]
```

The library as the records the file holds — one, for one object and channel.

# `size`

```elixir
@spec size(t()) :: non_neg_integer()
```

How many nodes the library holds.

# `write`

```elixir
@spec write(t(), Path.t(), keyword()) :: :ok | {:error, Quiddity.Error.t()}
```

Writes the library, gzipped, at `path` — the shape `Monty.Studio.Memory` reads.

A file the format's reader can rebuild is the whole contract, so a write that
fails is an error rather than a partial file that looks like a memory.

---

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