# `RDF.Statement`
[🔗](https://github.com/rdf-elixir/rdf-ex/blob/v3.0.1/lib/rdf/model/statement.ex#L1)

Helper functions for RDF statements.

An RDF statement is either a `RDF.Triple` or a `RDF.Quad`.

# `coercible`

```elixir
@type coercible() :: RDF.Triple.coercible() | RDF.Quad.coercible()
```

# `coercible_graph_name`

```elixir
@type coercible_graph_name() :: graph_name() | atom() | String.t()
```

# `coercible_object`

```elixir
@type coercible_object() :: object() | any()
```

# `coercible_predicate`

```elixir
@type coercible_predicate() :: RDF.Resource.coercible()
```

# `coercible_subject`

```elixir
@type coercible_subject() :: RDF.Resource.coercible()
```

# `graph_name`

```elixir
@type graph_name() :: RDF.Resource.t() | nil
```

# `object`

```elixir
@type object() :: RDF.Resource.t() | RDF.Literal.t()
```

# `position`

```elixir
@type position() :: :subject | :predicate | :object | :graph_name
```

# `predicate`

```elixir
@type predicate() :: RDF.Resource.t()
```

# `qualified_term`

```elixir
@type qualified_term() :: {position(), RDF.Term.t() | nil}
```

# `subject`

```elixir
@type subject() :: RDF.Resource.t()
```

# `t`

```elixir
@type t() :: RDF.Triple.t() | RDF.Quad.t()
```

# `term_mapping`

```elixir
@type term_mapping() :: (qualified_term() -&gt; any() | nil)
```

# `bnodes`

```elixir
@spec bnodes(t()) :: [RDF.BlankNode.t()]
```

Returns a list of all `RDF.BlankNode`s within the given `statement`.

# `coerce`

```elixir
@spec coerce(coercible(), RDF.PropertyMap.t() | nil) :: RDF.Triple.t() | RDF.Quad.t()
```

Creates a `RDF.Statement` tuple with proper RDF values.

An error is raised when the given elements are not coercible to RDF values.

## Examples

    iex> RDF.Statement.coerce {"http://example.com/S", "http://example.com/p", 42}
    {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42)}
    iex> RDF.Statement.coerce {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
    {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}

# `coerce_graph_name`

```elixir
@spec coerce_graph_name(coercible_graph_name()) :: graph_name()
```

Coerces the given `value` to a valid graph context of an RDF statement.

Raises an `RDF.Quad.InvalidGraphContextError` when the value can not be coerced.

# `coerce_object`

```elixir
@spec coerce_object(coercible_object()) :: object()
```

Coerces the given `value` to a valid object of an RDF statement.

# `coerce_predicate`

```elixir
@spec coerce_predicate(coercible_predicate()) :: predicate()
```

Coerces the given `value` to a valid predicate of an RDF statement.

Raises an `RDF.Triple.InvalidPredicateError` when the value can not be coerced.

# `coerce_predicate`

```elixir
@spec coerce_predicate(coercible_predicate(), RDF.PropertyMap.t()) :: predicate()
```

Coerces the given `term` to a valid predicate of an RDF statement using a `RDF.PropertyMap`.

Raises an `RDF.Triple.InvalidPredicateError` when the value can not be coerced.

# `coerce_subject`

```elixir
@spec coerce_subject(coercible_subject()) :: subject()
```

Coerces the given `value` to a valid subject of an RDF statement.

Raises an `RDF.Triple.InvalidSubjectError` when the value can not be coerced.

# `default_property_mapping`

```elixir
@spec default_property_mapping(RDF.PropertyMap.t()) :: term_mapping()
```

# `graph_name`

The graph name component of a statement.

## Examples

    iex> RDF.Statement.graph_name {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}
    ~I<http://example.com/Graph>
    iex> RDF.Statement.graph_name {"http://example.com/S", "http://example.com/p", 42}
    nil

# `has_bnode?`

```elixir
@spec has_bnode?(t()) :: boolean()
```

Returns whether the given `statement` contains a blank node.

# `include_value?`

```elixir
@spec include_value?(t(), any()) :: boolean()
```

Returns whether the given `value` is a component of the given `statement`.

# `map`

```elixir
@spec map(t(), term_mapping()) ::
  RDF.Triple.mapping_value() | RDF.Quad.mapping_value() | nil | nil
```

Returns a tuple of native Elixir values from a `RDF.Statement` of RDF terms.

Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.

The optional second argument allows to specify a custom mapping with a function
which will receive a tuple `{statement_position, rdf_term}` where
`statement_position` is one of the atoms `:subject`, `:predicate`, `:object` or
`:graph_name`, while `rdf_term` is the RDF term to be mapped. When the given
function returns `nil` this will be interpreted as an error and will become
the overhaul result of the `values/2` call.

## Examples

    iex> {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
    ...> |> RDF.Statement.map(fn
    ...>      {:subject, subject} ->
    ...>        subject |> to_string() |> String.last()
    ...>      {:predicate, predicate} ->
    ...>        predicate |> to_string() |> String.last() |> String.to_atom()
    ...>      {:object, object} ->
    ...>        RDF.Term.value(object)
    ...>      {:graph_name, graph_name} ->
    ...>        graph_name
    ...>    end)
    {"S", :p, 42, ~I<http://example.com/Graph>}

# `new`

Creates a `RDF.Triple` or `RDF.Quad` with proper RDF values.

An error is raised when the given elements are not coercible to RDF values.

Note: The `RDF.statement` function is a shortcut to this function.

## Examples

    iex> RDF.Statement.new({EX.S, EX.p, 42})
    {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42)}

    iex> RDF.Statement.new({EX.S, EX.p, 42, EX.Graph})
    {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")}

    iex> RDF.Statement.new({EX.S, :p, 42, EX.Graph}, RDF.PropertyMap.new(p: EX.p))
    {RDF.iri("http://example.com/S"), RDF.iri("http://example.com/p"), RDF.literal(42), RDF.iri("http://example.com/Graph")}

# `new`

# `new`

# `object`

The object component of a statement.

## Examples

    iex> RDF.Statement.object {"http://example.com/S", "http://example.com/p", 42}
    RDF.literal(42)

# `predicate`

The predicate component of a statement.

## Examples

    iex> RDF.Statement.predicate {"http://example.com/S", "http://example.com/p", 42}
    ~I<http://example.com/p>

# `subject`

The subject component of a statement.

## Examples

    iex> RDF.Statement.subject {"http://example.com/S", "http://example.com/p", 42}
    ~I<http://example.com/S>

# `valid?`

```elixir
@spec valid?(RDF.Triple.t() | RDF.Quad.t() | any()) :: boolean()
```

Checks if the given tuple is a valid RDF statement, i.e. RDF triple or quad.

The elements of a valid RDF statement must be RDF terms. On the subject
position only IRIs and blank nodes allowed, while on the predicate and graph
context position only IRIs allowed. The object position can be any RDF term.

# `valid_graph_name?`

```elixir
@spec valid_graph_name?(graph_name() | any()) :: boolean()
```

# `valid_object?`

```elixir
@spec valid_object?(object() | any()) :: boolean()
```

# `valid_predicate?`

```elixir
@spec valid_predicate?(predicate() | any()) :: boolean()
```

# `valid_subject?`

```elixir
@spec valid_subject?(subject() | any()) :: boolean()
```

# `values`

```elixir
@spec values(
  t(),
  keyword()
) :: RDF.Triple.mapping_value() | RDF.Quad.mapping_value() | nil
```

Returns a tuple of native Elixir values from a `RDF.Statement` of RDF terms.

When a `:context` option is given with a `RDF.PropertyMap`, predicates will
be mapped to the terms defined in the `RDF.PropertyMap`, if present.

Returns `nil` if one of the components of the given tuple is not convertible via `RDF.Term.value/1`.

## Examples

    iex> RDF.Statement.values {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42)}
    {"http://example.com/S", "http://example.com/p", 42}

    iex> RDF.Statement.values {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42), ~I<http://example.com/Graph>}
    {"http://example.com/S", "http://example.com/p", 42, "http://example.com/Graph"}

    iex> {~I<http://example.com/S>, ~I<http://example.com/p>, RDF.literal(42)}
    ...> |> RDF.Statement.values(context: %{p: ~I<http://example.com/p>})
    {"http://example.com/S", :p, 42}

---

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