Repair behaviour of (during $x => assert x).

This commit is contained in:
Tony Garnock-Jones 2022-01-16 15:11:01 +01:00
parent 4265343cc8
commit f8b06ff02a
2 changed files with 36 additions and 28 deletions

View File

@ -8,44 +8,51 @@ import { fromObserve, Observe, toObserve } from '../gen/dataspace.js';
import * as P from '../gen/dataspacePatterns.js'; import * as P from '../gen/dataspacePatterns.js';
export type DataspaceOptions = { export type DataspaceOptions = {
tracer?: (event: '+' | '-' | '!', assertion: Assertion, dataspace: Dataspace) => void, tracer?: (event: '+' | '-' | '!',
assertion: Assertion,
dataspace: Dataspace,
is_significant: boolean) => void,
dumpIndex?: boolean, dumpIndex?: boolean,
}; };
export class Dataspace implements Partial<Entity> { export class Dataspace implements Partial<Entity> {
readonly options: DataspaceOptions; readonly options: DataspaceOptions;
readonly index = new Index(); readonly index = new Index();
readonly handleMap = new IdentityMap<Handle, [Assertion, Observe | undefined]>(); readonly handleMap = new IdentityMap<Handle, Assertion>();
constructor(options?: DataspaceOptions) { constructor(options?: DataspaceOptions) {
this.options = options ?? {}; this.options = options ?? {};
} }
assert(v: Assertion, handle: Handle): void { assert(v: Assertion, handle: Handle): void {
this.options.tracer?.('+', v, this); const is_new = this.index.addAssertion(v);
this.index.addAssertion(v); this.options.tracer?.('+', v, this, is_new);
const o = toObserve(v); if (is_new) {
if (o !== void 0) { const o = toObserve(v);
this.index.addObserver(o.pattern, o.observer); if (o !== void 0) {
this.index.addObserver(o.pattern, o.observer);
}
if (this.options.dumpIndex ?? false) this.index.dump();
} }
if (this.options.dumpIndex ?? false) this.index.dump(); this.handleMap.set(handle, v);
this.handleMap.set(handle, [v, o]);
} }
retract(handle: Handle): void { retract(handle: Handle): void {
const entry = this.handleMap.get(handle); const v = this.handleMap.get(handle);
if (entry === void 0) return; if (v === void 0) return;
const [v, o] = entry; const is_last = this.index.removeAssertion(v);
this.options.tracer?.('-', v, this); this.options.tracer?.('-', v, this, is_last);
if (o !== void 0) { if (is_last) {
this.index.removeObserver(o.pattern, o.observer); const o = toObserve(v);
if (o !== void 0) {
this.index.removeObserver(o.pattern, o.observer);
}
if (this.options.dumpIndex ?? false) this.index.dump();
} }
this.index.removeAssertion(v);
if (this.options.dumpIndex ?? false) this.index.dump();
} }
message(v: Assertion): void { message(v: Assertion): void {
this.options.tracer?.('!', v, this); this.options.tracer?.('!', v, this, true);
this.index.deliverMessage(v); this.index.deliverMessage(v);
} }

View File

@ -83,9 +83,8 @@ export class Index {
} }
} }
adjustAssertion(outerValue: Assertion, delta: number): ChangeDescription { adjustAssertion(outerValue: Assertion, delta: number): boolean {
let net = this.allAssertions.change(outerValue, delta); switch (this.allAssertions.change(outerValue, delta)) {
switch (net) {
case ChangeDescription.ABSENT_TO_PRESENT: case ChangeDescription.ABSENT_TO_PRESENT:
this.root.modify( this.root.modify(
EventType.ADDED, EventType.ADDED,
@ -97,7 +96,7 @@ export class Index {
h.observers.forEach((captureMap, observer) => h.observers.forEach((captureMap, observer) =>
captureMap.set(vs, Turn.active.assert(observer, vs))); captureMap.set(vs, Turn.active.assert(observer, vs)));
}); });
break; return true;
case ChangeDescription.PRESENT_TO_ABSENT: case ChangeDescription.PRESENT_TO_ABSENT:
this.root.modify( this.root.modify(
@ -112,17 +111,19 @@ export class Index {
captureMap.delete(vs); captureMap.delete(vs);
}); });
}); });
break; return true;
default:
return false;
} }
return net;
} }
addAssertion(v: Assertion) { addAssertion(v: Assertion): boolean {
this.adjustAssertion(v, +1); return this.adjustAssertion(v, +1);
} }
removeAssertion(v: Assertion) { removeAssertion(v: Assertion): boolean {
this.adjustAssertion(v, -1); return this.adjustAssertion(v, -1);
} }
deliverMessage(v: Assertion, leafCallback: (l: Leaf, v: Assertion) => void = _nop) { deliverMessage(v: Assertion, leafCallback: (l: Leaf, v: Assertion) => void = _nop) {