Packages

Guesswork is a logic programming library for Elixir. It is heavily inspired by Prolog, but attempts to use idiomatic Elixir when expressing problems and their solutions.

Current section

Files

Jump to
guesswork lib guesswork ast assign.ex
Raw

lib/guesswork/ast/assign.ex

defmodule Guesswork.Ast.Assign do
@moduledoc """
A simple assignment of a value to a variable.
"""
defstruct [:binding, :value]
alias Guesswork.Ast.Variable
alias Guesswork.Ast.Term
alias Guesswork.Ast.Statement.Opts
alias Guesswork.Answer
alias Guesswork.Answer.Binding
alias Guesswork.Telemetry.EventHandler
@type t() :: %__MODULE__{binding: Variable.t() | Term.entity(), value: Term.entity()}
@spec new(Variable.t(), Term.entity()) :: t()
def new(variable, value), do: %__MODULE__{binding: variable, value: value}
defimpl Guesswork.Ast.Term do
alias Guesswork.Ast.Assign
def concrete?(%Assign{binding: %Variable{}}), do: false
def concrete?(_), do: true
def get_variables(%Assign{binding: %Variable{} = variable}), do: [variable]
def get_variables(_), do: []
end
defimpl Guesswork.Ast.Statement do
alias Guesswork.Ast.Assign
def simplify(statement) do
statement
end
def substitute(%Assign{binding: binding} = statement, env) do
case Map.fetch(env, binding) do
:error -> statement
{:ok, value} -> %Assign{statement | binding: value}
end
end
def resolve(
%Assign{binding: %Variable{display: display}, value: value},
negated,
%Opts{query_id: query_id}
) do
:telemetry.execute(EventHandler.assignment_event_name(), %{count: 1}, %{query_id: query_id})
[
%Answer{
tests: [],
bindings: %{display => Binding.new(value, negated)},
query_id: query_id
}
]
end
def resolve(
%Assign{binding: bound, value: value},
negated,
%Opts{query_id: query_id}
)
when bound == value != negated,
do: [Answer.new(query_id)]
def resolve(_statement, _negated, _opts), do: []
end
end