Skip to content

Commit

Permalink
Merge pull request #240 from TimKam/238-keep-initial-priorities
Browse files Browse the repository at this point in the history
Allow keeping belief priorities
  • Loading branch information
TimKam authored May 6, 2024
2 parents 20bb0c7 + 45a80f0 commit 4960fb5
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 9 deletions.
19 changes: 16 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,22 @@ After applying the belief update, our agent's belief base is as follows:
Note that in detail, the priorities are interpreted as follows:
* If a belief exists in the update, but not in the agent's belief base, this belief is added.
* If the belief's priority is 0 in the belief base and a belief with the same key exists in the update, the agent's belief is overridden; this behavior is desired for beliefs that are generally defeasible.
* If a belief's priority in the update is higher than the same belief's priority in the agent's belief base, the agent's belief is overridden.
* If a belief exists in the update, but not in the agent's belief base, this belief is added.
* If the belief's priority is 0 in the belief base and a belief with the same key exists in the update, the agent's belief is overridden; this behavior is desired for beliefs that are generally defeasible.
* If a belief's priority in the update is higher than the same belief's priority in the agent's belief base, the agent's belief is overridden.
A potential issue that the belief revision function we use above does not address is that it essentially requires the *inflation* of priorities in case of regular successful revisions of beliefs with a non-zero priority.
For example, in order to update ``the belief \verb|propertyValue: { value: 500000, priority: 1 }``, a new ``propertyValue`` belief can only defeat the belief if its priority is ``2`` or higher; the subsequent defeater will then require a priority of ``3``, and so on.
We can address this issue by defining whether a particular belief (or beliefs in general) should, when defeated, adopt the priority of their defeater.
When using ``JSson.revisionFunctions.revisePriorityStatic`` as our belief revision function, the priority of the initial beliefs are maintained. Alternatively, we can specify whether or not a belief's priority should be updated, on the level of the individual belief:
```JavaScript
const beliefBase = {
isRaining: Belief('isRaining', true, Infinity, true),
temperature: Belief('temperature', 10, Infinity, false)
}
```
## Messaging
JS-son agents can send "private" messages to any other JS-son agent, which the environment will then relay to this agent only.
Expand Down
4 changes: 2 additions & 2 deletions spec/src/agent/Belief.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ describe('belief()', () => {
expect(Belief('test', 'test')).toEqual({ test: 'test' })
})

it('should create a new belief with the specified key, value (explicitly managed), and priority', () => {
expect(Belief('test', 'test', 1)).toEqual({ test: 'test', value: 'test', priority: 1 })
it('should create a new belief with the specified key, value (explicitly managed), priority, and priority update spec', () => {
expect(Belief('test', 'test', 1)).toEqual({ test: 'test', value: 'test', priority: 1, updatePriority: false })
})

it('should not throw a warning if belief is of a JSON data type', () => {
Expand Down
37 changes: 36 additions & 1 deletion spec/src/agent/beliefRevision/revisionFunctions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ const Belief = require('../../../../src/agent/Belief')
const {
reviseSimpleNonmonotonic,
reviseMonotonic,
revisePriority } = require('../../../../src/agent/beliefRevision/revisionFunctions')
revisePriority,
revisePriorityStatic } = require('../../../../src/agent/beliefRevision/revisionFunctions')

const {
beliefs,
Expand Down Expand Up @@ -98,4 +99,38 @@ describe('revisionFunctions', () => {
expect(newAgent.beliefs.isRaining.value).toBe(true)
expect(newAgent.beliefs.temperature.value).toEqual(10)
})

it('should allow configuring a belief such that its initial priority is kept', () => {
const beliefBase = { isRaining: Belief('isRaining', true, 1, false) }

const update = { isRaining: Belief('isRaining', false, 2) }

const newAgent = new Agent({
id: 'myAgent',
beliefs: beliefBase,
desires,
plans,
selfUpdatesPossible: false,
reviseBeliefs: revisePriority
})
newAgent.next(update)
expect(newAgent.beliefs.isRaining.priority).toBe(1)
})

it('should allow configuring a priority belief revision function such that the initial priorities of it beliefs are generally kept', () => {
const beliefBase = { isRaining: Belief('isRaining', true, 1) }

const update = { isRaining: Belief('isRaining', false, 2) }

const newAgent = new Agent({
id: 'myAgent',
beliefs: beliefBase,
desires,
plans,
selfUpdatesPossible: false,
reviseBeliefs: revisePriorityStatic
})
newAgent.next(update)
expect(newAgent.beliefs.isRaining.priority).toBe(1)
})
})
4 changes: 3 additions & 1 deletion src/agent/Belief.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@ const warning = 'JS-son: Created belief with non-JSON object, non-JSON data type
* @param {string} id the belief's unique identifier
* @param {any} value the belief's value
* @param {number} priority the belief's priority in case of belief revision; optional
* @param {boolean} updatePriority whether in case of a belief update, the priority of the defeating belief should be adopted; optional, defaults to true
* @returns {object} JS-son agent belief
*/
const Belief = (id, value, priority) => {
const Belief = (id, value, priority, updatePriority=false) => {
const belief = {}
belief[id] = value
if (priority || priority === 0) {
belief.priority = priority
belief['value'] = value
belief.updatePriority = updatePriority
}
try {
const parsedBelief = JSON.parse(JSON.stringify(belief))
Expand Down
22 changes: 20 additions & 2 deletions src/agent/beliefRevision/revisionFunctions.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,31 @@ const reviseMonotonic = (oldBeliefs, newBeliefs) => ({ ...newBeliefs, ...oldBeli
const revisePriority = (oldBeliefs, newBeliefs) => Object.fromEntries(
new Map(
Object.keys(newBeliefs).map(key =>
!key in oldBeliefs || oldBeliefs[key].priority == 0 || oldBeliefs[key].priority < newBeliefs[key].priority ? [key, newBeliefs[key]] : [key, oldBeliefs[key]]
!key in oldBeliefs || oldBeliefs[key].priority == 0 || oldBeliefs[key].priority < newBeliefs[key].priority ? oldBeliefs[key].updatePriority ? [key, newBeliefs[key]] : [key, { ...oldBeliefs[key], value: newBeliefs[key].value }] : [key, oldBeliefs[key]]
)
)
)

/**
* Revises beliefs by merging old and new beliefs such that an old belief overrides a new one in. Does not update belief priorities.
* case of conflict
* @param {object} oldBeliefs Old belief base (JSON object of beliefs)
* @param {object} newBeliefs New belief base (JSON object of beliefs)
* @returns Revised belief base (JSON object of beliefs)
*/

const revisePriorityStatic = (oldBeliefs, newBeliefs) => revisePriority(Object.fromEntries(
new Map(
Object.keys(oldBeliefs).map(key => [
key,
{ ...oldBeliefs[key], updatePriority: false }
])
)
), newBeliefs)

module.exports = {
reviseSimpleNonmonotonic,
reviseMonotonic,
revisePriority
revisePriority,
revisePriorityStatic
}

0 comments on commit 4960fb5

Please sign in to comment.