Current section

Files

Jump to
shot_ds lib shot_ds data term.ex
Raw

lib/shot_ds/data/term.ex

defmodule ShotDs.Data.Term do
@moduledoc """
Represents a Hol term as directed acyclic graph (DAG).
All terms contain a deterministic ID assigned by `ShotDs.Stt.TermFactory`.
Note that terms are in βη-normal form, i.e., fully β-reduced and η-expanded.
Besides the obvious fields `:head`, `:args` and `:type`, two accessor fields
are implemented for efficiency: `:fvars` contains all free variables
occurring in the term, `:max_num` represents the index of the highest bound
variable. Abstractions are identified by the `:bvars` field.
"""
alias ShotDs.Data.Declaration
alias ShotDs.Data.Type
@enforce_keys [:id, :head, :type]
defstruct [:id, :head, :type, bvars: [], args: [], fvars: [], max_num: 0]
@typedoc """
A term's id is given by an atomic positive integer where 0 denotes a dummy.
"""
@type term_id :: non_neg_integer()
@typedoc """
The type of a term. The fields `:id`, `:head` and `:type` are required.
"""
@type t :: %__MODULE__{
id: term_id(),
bvars: [Declaration.t()],
head: Declaration.t(),
args: [term_id()],
type: Type.t(),
fvars: [Declaration.t()],
max_num: non_neg_integer()
}
end
defimpl String.Chars, for: ShotDs.Data.Term do
def to_string(%{bvars: bvars, head: head, args: args, type: type}) do
args_str = if args == [], do: "", else: "[#{length(args)} args]"
bvars_str = String.duplicate("λ", length(bvars))
case {bvars_str, args_str} do
{"", ""} -> "#{head}"
{"", a} -> "(#{head} #{a})_#{type}"
{b, ""} -> "(#{b}. #{head})_#{type}"
{b, a} -> "(#{b}. #{head} #{a})_#{type}"
end
end
end