1

I'm exploring Apple's GameplayKit APIs and I am currently very confused by the way that GKRuleSystem evaluates its rules. The documentation says that the salience property determines the order of evaluation, with higher-salience rules being evaluated first (https://developer.apple.com/library/ios/documentation/GameplayKit/Reference/GKRule_Class/index.html#//apple_ref/occ/instp/GKRule/salience). But in practice, this does not appear to happen:

let twoRuleSystem = GKRuleSystem()
let stateConditionA = "A"
let stateConditionB = "B"
let fact = "A"

let stronglyAssert = NSPredicate(format: "state.\(stateConditionA) = true")
let weaklyRetract = NSPredicate(format: "state.\(stateConditionB) = true")
let strongRule = GKRule(predicate: stronglyAssert, assertingFact: fact, grade: 1.0)
let weakRule = GKRule(predicate: weaklyRetract, retractingFact: fact, grade: 0.25)

strongRule.salience = 10
weakRule.salience = 1

twoRuleSystem.addRulesFromArray([strongRule, weakRule])

twoRuleSystem.state[stateConditionA] = true
twoRuleSystem.state[stateConditionB] = true
twoRuleSystem.reset()
twoRuleSystem.evaluate()

print("The fact \(fact) evaluates to \(twoRuleSystem.gradeForFact(fact))")
// prints "The fact A evaluates to 1.0"

If I reverse the salience of the two facts, then the result is "The fact A evaluates to 0.75".

I would expect that when my strongRule has salience of 10, it will be evaluated first, and the fact A will be asserted with a value of 1.0. Then the weakRule will be evaluated, and fact A will be retracted with a value of 0.25, resulting in a fact grade of 0.75. But this only works if the weakRule has a higher salience.

This confuses me even more, because if the weakRule is being evaluated first, I would expect the value of fact A to be 0; the fact's grade can only be a value from 0 to 1.0. Then I would expect the strongRule to be evaluated and assert fact A with a grade of 1.0. But that is not what's happening.

Uzziel
  • 300
  • 2
  • 6

1 Answers1

1

I got a response from Apple - this is a confirmed bug. GKRuleSystem doesn't evaluate its rules in the order that they're added. You have to use the salience value to guarantee the order of rule execution.

Also, lower numbers mean higher salience: a rule with salience of 1 will get evaluated before a rule with salience of 2.

Uzziel
  • 300
  • 2
  • 6