Repair behaviour of (during $x => assert x).
This commit is contained in:
parent
4265343cc8
commit
f8b06ff02a
|
@ -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);
|
||||||
|
if (is_new) {
|
||||||
const o = toObserve(v);
|
const o = toObserve(v);
|
||||||
if (o !== void 0) {
|
if (o !== void 0) {
|
||||||
this.index.addObserver(o.pattern, o.observer);
|
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, o]);
|
}
|
||||||
|
this.handleMap.set(handle, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 (is_last) {
|
||||||
|
const o = toObserve(v);
|
||||||
if (o !== void 0) {
|
if (o !== void 0) {
|
||||||
this.index.removeObserver(o.pattern, o.observer);
|
this.index.removeObserver(o.pattern, o.observer);
|
||||||
}
|
}
|
||||||
this.index.removeAssertion(v);
|
|
||||||
if (this.options.dumpIndex ?? false) this.index.dump();
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Reference in New Issue