defmodule Retex.Fact.HasAttribute do
@moduledoc "Attribute values that a Wme should have in order for this condition to be true"
defstruct owner: nil, attribute: nil, predicate: nil, value: nil
@type owner :: String.t() | atom()
@type attribute :: String.t() | atom()
@type predicate :: :== | :=== | :!== | :!= | :> | :< | :<= | :>= | :in
@type value :: any()
@type fields :: [owner: owner(), attribute: attribute(), predicate: predicate(), value: value()]
@type t :: %Retex.Fact.HasAttribute{
owner: owner(),
attribute: attribute(),
predicate: predicate(),
value: value()
}
@spec new(fields()) :: t()
def new(fields) do
struct(__MODULE__, fields)
end
defimpl Retex.Protocol.AlphaNetwork do
alias Retex.{Fact.HasAttribute, Node}
def append(%HasAttribute{} = condition, {graph, test_nodes}) do
%{attribute: attribute, owner: class, predicate: predicate, value: value} = condition
condition_id = Retex.hash(condition)
type_node = Node.Type.new(class)
select_node = Node.Select.new(class, attribute)
test_node = Node.Test.new([predicate, value], condition_id)
new_graph =
graph
|> Graph.add_vertex(type_node)
|> Graph.add_edge(Retex.root_vertex(), type_node)
|> Graph.add_vertex(select_node)
|> Graph.add_edge(type_node, select_node)
|> Graph.add_vertex(test_node)
|> Graph.add_edge(select_node, test_node)
{new_graph, [test_node | test_nodes]}
end
end
end