Skip to content

Commit

Permalink
feat(logic): add term_to_atom/2 predicate
Browse files Browse the repository at this point in the history
  • Loading branch information
ccamel committed Oct 13, 2024
1 parent 025dd8b commit 96043c2
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
1 change: 1 addition & 0 deletions x/logic/interpreter/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@ var registry = orderedmap.New[string, any](
{Key: "eddsa_verify/4", Value: predicate.EDDSAVerify},
{Key: "ecdsa_verify/4", Value: predicate.ECDSAVerify},
{Key: "string_bytes/3", Value: predicate.StringBytes},
{Key: "term_to_atom/2", Value: predicate.TermToAtom},
}...),
)

Expand Down
52 changes: 52 additions & 0 deletions x/logic/predicate/atom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package predicate

import (
"fmt"
"strings"

"github.com/axone-protocol/prolog/engine"

"github.com/axone-protocol/axoned/v10/x/logic/prolog"
)

// TermToAtom is a predicate that describes Atom as a term that unifies with Term.
//
// # Signature
//
// term_to_atom(?Term, ?Atom)
//
// where:
// - Term is a term that unifies with Atom.
// - Atom is an atom.
//
// When Atom is instantiated, Atom is parsed and the result unified with Term. If Atom has no valid syntax,
// a syntax_error exception is raised. Otherwise, Term is “written” on Atom using write_term/2 with the option quoted(true).
//
// # Example
//
// # Convert the atom to a term.
// - term_to_atom(foo, foo).
func TermToAtom(vm *engine.VM, term, atom engine.Term, cont engine.Cont, env *engine.Env) *engine.Promise {
switch {
case prolog.IsGround(term, env):
var strBuilder strings.Builder
os := engine.NewOutputTextStream(&strBuilder)
return engine.WriteTerm(vm, os, term, engine.List(engine.NewAtom("quoted").Apply(prolog.AtomTrue)),
func(env *engine.Env) *engine.Promise {
return engine.Unify(vm, prolog.StringToAtom(strBuilder.String()), atom, cont, env)
}, env)
case prolog.IsGround(atom, env):
atom, err := prolog.AssertAtom(atom, env)
if err != nil {
return engine.Error(err)
}
is := engine.NewInputTextStream(strings.NewReader(fmt.Sprintf("%s.", atom)))
parsedAtom := engine.NewVariable()
return engine.ReadTerm(vm, is, parsedAtom, engine.List(),
func(env *engine.Env) *engine.Promise {
return engine.Unify(vm, term, parsedAtom, cont, env)
}, env)
}

return engine.Error(engine.InstantiationError(env))
}

0 comments on commit 96043c2

Please sign in to comment.