Giter Site home page Giter Site logo

go's Introduction

trealla-go GoDoc

import "github.com/trealla-prolog/go/trealla"

Prolog interface for Go using Trealla Prolog and Wasmtime. It's pretty fast. Not as fast as native Trealla, but pretty dang fast (about 2x slower than native).

Development Status: inching closer to stability

Caveats

  • Beta status, API will probably change
    • API is relatively stable now.

Install

go get github.com/trealla-prolog/go

Note: the module is under github.com/trealla-prolog/go, not [...]/go/trealla. go.dev is confused about this and will pull a very old version if you try to go get the trealla package.

Usage

This library uses WebAssembly to run Trealla, executing Prolog queries in an isolated environment.

import "github.com/trealla-prolog/go/trealla"

func main() {
	// load the interpreter and (optionally) grant access to the current directory
	pl := trealla.New(trealla.WithPreopen("."))
	// run a query; cancel context to abort it
	ctx := context.Background()
	query := pl.Query(ctx, "member(X, [1, foo(bar), c]).")

	// calling Close is not necessary if you iterate through the whole result set
	// but it doesn't hurt either
	defer query.Close() 

	// iterate through answers
	for query.Next(ctx) {
		answer := query.Current()
		x := answer.Solution["X"]
		fmt.Println(x) // 1, trealla.Compound{Functor: "foo", Args: [trealla.Atom("bar")]}, "c"
	}

	// make sure to check the query for errors
	if err := query.Err(); err != nil {
		panic(err)
	}
}

Single query

Use QueryOnce when you only want a single answer.

pl := trealla.New()
answer, err := pl.QueryOnce(ctx, "succ(41, N).")
if err != nil {
	panic(err)
}

fmt.Println(answer.Stdout)
// Output: hello world

Binding variables

You can bind variables in the query using the WithBind and WithBinding options. This is a safe and convenient way to pass data into the query. It is OK to pass these multiple times.

pl := trealla.New()
answer, err := pl.QueryOnce(ctx, "write(X)", trealla.WithBind("X", trealla.Atom("hello world")))
if err != nil {
	panic(err)
}

fmt.Println(answer.Stdout)
// Output: hello world

Scanning solutions

You can scan an answer's substitutions directly into a struct or map, similar to ichiban/prolog.

Use the prolog:"VariableName" struct tag to manually specify a variable name. Otherwise, the field's name is used.

answer, err := pl.QueryOnce(ctx, `X = 123, Y = abc, Z = ["hello", "world"].`)
if err != nil {
	panic(err)
}

var result struct {
	X  int
	Y  string
	Hi []string `prolog:"Z"`
}
// make sure to pass a pointer to the struct!
if err := answer.Solution.Scan(&result); err != nil {
	panic(err)
}

fmt.Printf("%+v", result)
// Output: {X:123 Y:abc Hi:[hello world]}

Documentation

See package trealla's documentation for more details and examples.

Builtins

These additional predicates are built in:

  • crypto_data_hash/3
  • http_consult/1

WASM binary

This library embeds the Trealla WebAssembly binary in itself, so you can use it without any external dependencies. The binaries are currently sourced from guregu/trealla.

Building the WASM binary

If you'd like to build libtpl.wasm yourself:

# The submodule in src/trealla points to the current version
git submodule update --init --recursive
# Use the Makefile in the root of this project
make clean wasm
# Run the tests and benchmark to make sure it works
go test -v ./trealla -bench=.

Thanks

License

MIT. See ATTRIBUTION as well.

See also

go's People

Contributors

guregu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

go's Issues

wasm64 support

It's possible to exhaust the memory of the interpreter (4GB) by throwing a ton of concurrent queries at it. Using wasm64 should fix this.

Document / automate build process for Trealla binary

Currently I'm just kind of shoving the modules from lib/ into Trealla and building it. Need to improve this by maybe: automating this process, or including json/toplevel in the main project, or work around this with better consulting.

Persistent interpreter instances

Currently all queries go through a fresh interpreter. It would be nice to keep them alive so they can keep their knowledge base contents between requests.

I'm not sure how easy it will be because the stdin interfaces for Go WASM libraries don't look so great. Would be really nice to be able to pass an io.Reader to them.
Might be possible to work around by exporting Go/C functions and calling from Trealla FFI (need to add FFI to Trealla WASM first).

What can I do with "too many errors" ?

@guregu hi! ~
could you help me resolve this? just trying go build for stream but getting stopped at these errors. haven't encountered this before. also just updated go version; if that matters. Windows 11.

(sorry for posting here , but idk how else to contact you ๐Ÿ˜… )
image
image

Interop broken on Linux?

$ WASMTIME_BACKTRACE_DETAILS=1 go test -v ./trealla   
=== RUN   TestInterop/custom_function
2023/07/19 18:29:51 query: interop_test(X).
2023/07/19 18:29:51 query: X is 1 + 1.
=== NAME  TestInterop
    interop_test.go:34: trealla: query error: error while executing at wasm backtrace:
            0: <unknown>!pl_query
            1: 0x1fe1db - fn_sys_host_call_2
                            at /Users/guregu/code/trealla/fork/src/predicates.c:7692:12
            2: 0x234bc6 - start
                            at /Users/guregu/code/trealla/fork/src/query.c:1611:14
            3: 0x23b115 - execute
                            at /Users/guregu/code/trealla/fork/src/query.c:1823:9
            4: 0xf8327 - run
                            at /Users/guregu/code/trealla/fork/src/parser.c:3630:3
            5: 0x223e56 - pl_query
                            at /Users/guregu/code/trealla/fork/src/prolog.c:162:12
        
        Caused by:
            wasm trap: call stack exhausted

Works ok on macOS+arm64 so probably something weird going on. This is running in a VM though.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.