Skip to content

Commit

Permalink
fixed a new bug in the SWI Prolog implementation of the rule engine; …
Browse files Browse the repository at this point in the history
…added a maximum number of rule applications to assure termination, no matter which CHR implementation of CHR is used.
  • Loading branch information
Tom Gordon committed Jul 12, 2017
1 parent bcd4968 commit fb0c7a9
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/engine/caes/caes.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ type Statement struct {
type Rulebase interface {
// Infer returns true if the goals succeed and false if they fail.
// The list of strings returned represents the constraint store
Infer(goals []string) (bool, []string, error)
Infer(goals []string, max int) (bool, []string, error)
// AddRule adds a constraint handling rule to the rulebase
AddRule(name string, keep []string, delete []string, guard []string, body []string) error
}
Expand Down
5 changes: 4 additions & 1 deletion src/engine/caes/inference.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ import (
"github.com/carneades/carneades-4/src/engine/terms"
)

// maximum number of rule (scheme) applications when deriving arguments
const MAXRULEAPPS = 100000

// ArgDesc: Structure describing an argument instantiating an
// argument scheme. Represented in Prolog as argument(Scheme,Values)
type ArgDesc struct {
Expand Down Expand Up @@ -91,7 +94,7 @@ func (ag *ArgGraph) Infer() error {
goals = append(goals, k)
}

success, store, err := rb.Infer(goals)
success, store, err := rb.Infer(goals, MAXRULEAPPS)
if err != nil {
return err
}
Expand Down
30 changes: 25 additions & 5 deletions src/engine/caes/swichr.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"fmt"
"io/ioutil"
// "log"
"math"
"os"
"strings"
"time"
Expand Down Expand Up @@ -160,7 +161,11 @@ func writeCHR(t *SWIRulebase, goals []string, f *os.File) error {
n := len(goals)
for i := 0; i < n; i++ {
_, err = f.WriteString(" " + goals[i])
_, err = f.WriteString(".\n\n")
if i < n-1 {
_, err = f.WriteString(",\n")
} else {
_, err = f.WriteString(".\n\n")
}
}

if err != nil {
Expand All @@ -170,11 +175,26 @@ func writeCHR(t *SWIRulebase, goals []string, f *os.File) error {
}
}

// Infer: Apply an SWIRulebase to a list of goals. Return true
// if the goals are successfully solved, and false if the goals fail.
// Infer: Apply an SWIRulebase to a list of goals. The
// maximum amount of time alloted the SWI Prolog process depends
// on the maximum number of rules (schemes) which may be applied, max.
// Return true if the goals are successfully solved, and false if the goals fail.
// Return a list of the terms in the constraint store, if the goals
// succeeded. Returns an error if the rulebase could not be applied to the goals.
func (rb *SWIRulebase) Infer(goals []string) (bool, []string, error) {
func (rb *SWIRulebase) Infer(goals []string, max int) (bool, []string, error) {

// Assume that a rule or scheme application takes about 0.00015 seconds.
// If there is no limit to the number of rule applications (i.e. max==0),
// then limit the maximum amount of time alloted to the SWI Prolog to 15 seconds
// anyway, to assure termination. Otherwise limit the time to
// max * 0.00015 seconds, rounded up to the next second.

secsPerRule := 0.00015
timeLimit := 15 // seconds
if max > 0 {
timeLimit = int(math.Ceil(float64(max) * secsPerRule))
}

f, err := ioutil.TempFile(os.TempDir(), "swirulebase")
if err != nil {
return false, nil, err
Expand Down Expand Up @@ -207,7 +227,7 @@ func (rb *SWIRulebase) Infer(goals []string) (bool, []string, error) {
done <- cmd.Wait()
}()
finished := false
timer := time.After(timeLimit * time.Second)
timer := time.After(time.Duration(timeLimit) * time.Second)

scanner := bufio.NewScanner(stdout)
store := []string{}
Expand Down
1 change: 0 additions & 1 deletion src/engine/caes/swiplcmd_darwin.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

// resource limits for Prolog processes
const (
timeLimit = 15 // Seconds
stackLimit = "256m" // MB
)

Expand Down
1 change: 0 additions & 1 deletion src/engine/caes/swiplcmd_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

// resource limits for Prolog processes
const (
timeLimit = 15 // Seconds
stackLimit = "256m" // MB
)

Expand Down
1 change: 0 additions & 1 deletion src/engine/caes/swiplcmd_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (

// resource limits for Prolog processes
const (
timeLimit = 15 // Seconds
stackLimit = "256m" // MB
)

Expand Down

0 comments on commit fb0c7a9

Please sign in to comment.