Exo v0.1.3 Exo View Source

Logic programming in elixir.

Link to this section Summary

Types

We tried to support all unifiable datatype of elixir

Link to this section Types

Link to this type substitution() View Source
substitution() :: %{required(Exo.Var.t()) => value()}

We tried to support all unifiable datatype of elixir.

Link to this section Functions

Infix version of eqo/2.

      The Law of <~>
v <~> w  is the same as  w <~> v.

A macro for conj/2 — the logic and.

Example macro expanding :

ando do
  g1
  g2
  g3
end

# = expand to =>

conj(zzz(g1),
  conj(zzz(g2),
    zzz(g3)))
Link to this function call_with_empty_state(goal) View Source
call_with_empty_state(goal()) :: state_stream()
Link to this function call_with_fresh(fun) View Source
call_with_fresh((Exo.Var.t() -> goal())) :: goal()

A macro for a list ando/1 in oro/1.

      The Law of conde
To get more values from conde ,
pretend that the successful conde
line has failed, refreshing all variables
that got an association from that line.
  • conde is written conde and is pronounced “con-dee”.

  • conde is the default control mechanism of Prolog. See William F. Clocksin. Clause and Effect. Springer, 1997.

Link to this function deep_walk(v, s) View Source
deep_walk(value(), substitution()) :: value()
Link to this function empty_state() View Source
empty_state() :: Exo.State.t()

Perform the unification.

A goal that fails.

Link to this macro fresh(var_list, exp) View Source (macro)

A macro to create fresh logic variables.

      The Law of Fresh
If x is fresh, then  v <~> x  succeeds
and associates x with v.

Example macro expanding :

fresh [a, b, c] do
  g1
  g2
  g3
end

# = expand to =>

call_with_fresh fn a ->
  call_with_fresh fn b ->
    call_with_fresh fn c ->
      ando do
        g1
        g2
        g3
      end
    end
  end
end
Link to this function mk_reify(state_list) View Source
mk_reify([Exo.State.t()]) :: [value()]

A macro for disj/2 — the logic or.

Just like ando/1.

Link to this function reify_name(n) View Source
reify_name(integer()) :: atom()
Link to this function reify_state_with_1st_var(state) View Source
reify_state_with_1st_var(Exo.State.t()) :: value()
Link to this macro run(n, var, exp) View Source (macro)

A goal that succeeds.

Link to this function take_all(state_stream) View Source
take_all(state_stream()) :: [Exo.State.t()]

One-step walking

Walking until the value is not Var.t, which does not care about other vars in the result value.

Invers-η-delay

The act of performing an inverse-η on a goal and then wrapping its body in a lambda we refer to as inverse-η-delay.

Invers-η-delay is an operation that takes a goal and returns a goal, as the result of doing so on any goal g is a function from a state to a stream.