# `Ash.Filter.Predicate`
[🔗](https://github.com/ash-project/ash/blob/v3.24.1/lib/ash/filter/predicate.ex#L5)

Represents a predicate which can be simplified and/or compared with other predicates

Simplification and comparison will need more documentation, but ultimately it
is the logic that allows us to have a flexible and powerful authorization
system.

# `comparison`

```elixir
@type comparison() ::
  :unknown
  | :right_includes_left
  | :left_includes_right
  | :mutually_inclusive
  | :mutually_exclusive
```

# `predicate`

```elixir
@type predicate() :: struct()
```

# `bulk_compare`
*optional* 

```elixir
@callback bulk_compare([predicate()]) :: term()
```

As long as at least one predicate of the type defined in your module,
(and this callback is implemented), it will be called with all of the
other predicates present in a filter. The return value is relatively
complex, but it should be a list of boolean statements. E.g.
`{op, left, right}` and `{:not, predicate}` (nested as deep as necessary).

The best way to do it is to find lists of predicates that are mutually
exclusive or mutually inclusive, and pass those lists into
`Crux.Expression.at_most_one/1` and `Crux.Expression.all_or_none/1`

# `compare`
*optional* 

```elixir
@callback compare(predicate(), predicate()) :: comparison()
```

Compare two predicates. If possible, use `c:bulk_compare/1` instead

# `simplify`
*optional* 

```elixir
@callback simplify(predicate()) :: term()
```

Simplify to a more primitive statement.

For example, `x in [1, 2]` simplifies to `x == 1 or x == 2`.
Simplifying to filter expressions that already have comparisons
lets you avoid writing that logic for a given predicate.

# `compare`

Checks with each predicate module to see if it has a comparison
with

---

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