Skip to content

Commit

Permalink
up
Browse files Browse the repository at this point in the history
  • Loading branch information
xieyuheng committed Jun 21, 2024
1 parent fa63738 commit 1fed72c
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 7 deletions.
7 changes: 7 additions & 0 deletions TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,14 @@
>
> - https://github.com/cicada-lang/propagator/issues/2
fix `maybeUnwrapSupported` -- learn from `nary-unpacking`

`barometer` -- 的测试带上 `promises` -- 用论文中讲故事的方式来写测试

fix `isContradiction` for `Supported`

- `isContradiction` should be a generic

test about "a justified-intervals anomaly"

- 即 supports 的集合可能与 supported value put 进来的顺序有关
Expand Down
6 changes: 6 additions & 0 deletions src/dependency/supportedMerge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@ export function supportedMerge<A, B>(
): Supported<A | B> | Contradiction {
const mergedContent = merge(content.content, increment.content)

// 这里的 cases 可以写成更对称的样子,
// 但是这里为了效率(少调用 merge 的次数),
// 写的不是那么对称了。

if (mergedContent === content.content) {
// 正向和反向的 implies 代表等价。
if (implies(increment, content)) {
// 倾向于 content,除非 increment 真的有更多信息。
if (setIsSubsetOf(content.supports, increment.supports)) {
return content
} else {
Expand Down
13 changes: 13 additions & 0 deletions src/examples/barometer.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import assert from "node:assert"
import { test } from "node:test"
import { Cell, put } from "../cell/index.js"
import { Supported } from "../dependency/index.js"
import { Interval, intervalAlmostEqual } from "../interval/index.js"
import { run } from "../scheduler/index.js"
import { fallDuration, similarTriangles } from "./barometer.js"
Expand Down Expand Up @@ -72,3 +73,15 @@ test("examples / barometer / similarTriangles & fallDuration", async () => {
),
)
})

test("examples / barometer / with supported value", async () => {
const [barometerShadow, barometerHeight, buildingShadow, buildingHeight] =
similarTriangles()
put(buildingShadow, Supported(Interval(54.9, 55.1), new Set(["shadows"])))
put(barometerHeight, Supported(Interval(0.3, 0.32), new Set(["shadows"])))
put(barometerShadow, Supported(Interval(0.36, 0.37), new Set(["shadows"])))

// await run()

// console.log(buildingHeight)
})
15 changes: 9 additions & 6 deletions src/generic/defineGeneric.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@ export function defineGeneric(
if (options.default) {
return options.default(...args)
} else {
console.error({
who: "GenericDefinition",
constroctor: "defineGeneric",
definition,
args,
})
console.dir(
{
who: "GenericDefinition",
constroctor: "defineGeneric",
definition,
args,
},
{ depth: null },
)
throw new Error(`[GenericDefinition] Unhandled args and not default.`)
}
}
Expand Down
13 changes: 12 additions & 1 deletion src/merge/merge.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,18 @@ import { theContradiction } from "./Contradiction.js"
// treatment of their existing content versus incoming content. Having
// merge return the wrong one could lead to spurious infinite loops.

export const merge = defineGeneric() // no default, be explicit.
export const merge = defineGeneric({
default(...args) {
// no default, be explicit.
console.error({
who: "merge",
message: "Unhandled args.",
args,
})

throw new Error(`[merge] Unhandled args.`)
},
})

// Second argument is redundant for `merge`.
export function implies<A, B>(x: A, y: B): boolean {
Expand Down
11 changes: 11 additions & 0 deletions src/propagator/definePrimitive.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Cell, addPropagator, isNothing, nothing, put } from "../cell/index.js"
import { isSupported } from "../dependency/index.js"
import { schedule } from "../scheduler/index.js"
import type { MaybePromise } from "../utils/MaybePromise.js"
import { repeatApply } from "../utils/repeatApply.js"
Expand Down Expand Up @@ -86,6 +87,7 @@ function watch(cells: Array<Cell<any>>, propagator: Propagator): void {
function lift(
fn: (...args: Array<any>) => MaybePromise<any>,
): (...args: Array<Cell<any>>) => MaybePromise<any> {
fn = maybeUnwrapSupported(fn)
fn = skipIncompleteInputs(fn)

return (...inputs) => {
Expand All @@ -98,6 +100,15 @@ function lift(
}
}

function maybeUnwrapSupported(
fn: (...args: Array<any>) => MaybePromise<any>,
): (...args: Array<any>) => MaybePromise<any> {
return (...args) => {
args = args.map((arg) => (isSupported(arg) ? arg.content : arg))
return fn(...args)
}
}

// # 参数不全时的处理
// 函数只能在参数齐全的情况下才能作用,
// 因此代表函数的 propagator,
Expand Down

0 comments on commit 1fed72c

Please sign in to comment.