prolog icon indicating copy to clipboard operation
prolog copied to clipboard

adding and retracting facts

Open riccardopinosio opened this issue 2 years ago • 5 comments

Hello,

A further issue. I don't seem to be able to use the clause predicates to add/remove facts from the interpreter. What I tried:

func main() {
	p := prolog.New(nil, nil)
	if err := p.Exec(`
	dynamic(test_pred/1).
	assertz(test_pred(a)).
	`); err != nil {
		panic(err)
	}

	// Prolog program invocation takes a form of query.
	sols, err := p.Query(`
	test_pred(Res).
	`)
	if err != nil {
		panic(err)
	}
	defer sols.Close()

	// Iterates over solutions.
	for sols.Next() {
		// Prepare a struct with fields which name corresponds with a variable in the query.
		var s struct {
			Res string
		}
		if err := sols.Scan(&s); err != nil {
			panic(err)
		}
		fmt.Printf("%#v\n", s)
	}
}

This returns the error that dynamic/1 is static. Could you provide an example of how to use assertz, retract and similar with the API?

riccardopinosio avatar Mar 14 '22 20:03 riccardopinosio

dynamic(test_pred/1). which occurs in your code is a fact and has no influence at all on any other predicate.

To declare test_predi/1 dynamic, you must use the dynamic directive, i.e., with the functor (:-)/1. Example:

:- dynamic(test_pred/1).

triska avatar Mar 14 '22 20:03 triska

Thanks! That helped :) I'm a bit confused by the syntax because I would have expected :- without anything in the head to denote falsum. But I am using prolog now since a very long time so I am rusty. @triska can you recommend a good refresher prolog intro for someone familiar with logic?

riccardopinosio avatar Mar 14 '22 20:03 riccardopinosio

You can indeed read it as falsum: With

:- Goal.

We assert: Goal is false. Prolog yields logical consequences by constructing a resolution refutation of the (negated) query together with the program. So, to "refute" :- dynamic(test_pred/1). the predicate must be treated as being declared dynamic. Prolog, with answers, shows you: Here is a resolution refutation, which was obtained by treating the predicate as being declared dynamic, and thus in a sense constructs a "counterexample" to the assertion that the predicate is not declared dynamic, and this shows logical consequences of an interpretation where the declaration is the case!

This is analogous to posting any query: With:

?- Goal.

we assert: Goal is false. A counterexample to this assertion is a logical consequence of the program, and this is what Prolog shows in a logical interpretation, i.e., the results of such refutations.

triska avatar Mar 14 '22 20:03 triska

@ichiban am I correct in assuming that retractall/1 will also be implemented in a next release? I see some code implementing it in the main branch.

riccardopinosio avatar Mar 15 '22 17:03 riccardopinosio

@riccardopinosio Yes! ISO compliant ~~retract/1~~ will be in the next release! *I mean retractall/1.

ichiban avatar Mar 16 '22 12:03 ichiban

So the complete example is:

package main

import (
	"fmt"
	"github.com/ichiban/prolog"
)

func main() {
	p := prolog.New(nil, nil)
	if err := p.Exec(`
		:- dynamic(test_pred/1). % Declare test_pred/1 is dynamic.
		test_pred(a).            % Initial clauses follow.
		test_pred(b).            %
	`); err != nil {
		panic(err)
	}

	// You can modify dynamic predicates with asserta/1, assertz/1, and retract/1.
	if err := p.QuerySolution(`asserta(test_pred(c)).`).Err(); err != nil {
		panic(err)
	}

	if err := p.QuerySolution(`assertz(test_pred(d)).`).Err(); err != nil {
		panic(err)
	}

	if err := p.QuerySolution(`retract(test_pred(b)).`).Err(); err != nil {
		panic(err)
	}

	// Prolog program invocation takes a form of query.
	sols, err := p.Query(`test_pred(Res).`)
	if err != nil {
		panic(err)
	}
	defer sols.Close()

	// Iterates over solutions.
	for sols.Next() {
		// Prepare a struct with fields which name corresponds with a variable in the query.
		var s struct {
			Res string
		}
		if err := sols.Scan(&s); err != nil {
			panic(err)
		}
		fmt.Printf("%s\n", s.Res)
	}
}
c
a
d

ichiban avatar Dec 17 '22 02:12 ichiban

I'll close this issue for now. Feel free to reopen it!

ichiban avatar Dec 17 '22 02:12 ichiban