Skip to content

Commit 2032388

Browse files
committed
rename strongestBelief to beliefMergeManyStillBelieved
1 parent 728ac28 commit 2032388

8 files changed

+105
-11
lines changed

TODO.md

+3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
rename `isBeliefBelieved` to `isStillBelieved`
2+
extract `beliefMergeMany`
3+
14
# 4.4 Dependencies Improve Search
25

36
> https://github.com/cicada-lang/propagator/issues/4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
title: Propagator Model and Lattice
3+
date: 2024-09-16
4+
---
5+
6+
# Structural Subtyping 作为 Lattice
7+
8+
Structural Subtyping 作为 Lattice,
9+
可以理解为是一种结构化的构造新的 Lattice 的方式,
10+
已知一些 lattice,然后生成 record lattice。
11+
12+
可以理解为带有名字(record 的 key)的 product lattice,
13+
但是与 product 不同的是,key 出现与否可以给出额外的序关系。
14+
15+
例如:
16+
17+
```
18+
{ a: A, b: B, c: C } <= { a: A, b: B }
19+
{ a: A, b: { x: X, y: Y } } <= { a: A, b: { x: X } }
20+
```
21+
22+
一般的集合有:
23+
24+
```
25+
{a, b} <= {a, b, c}
26+
```
27+
28+
但是当把集合的元素理解为 record 的 key 时,就有:
29+
30+
```
31+
{a: Unit, b: Unit, c: Unit} <= {a: Unit, b: Unit}
32+
```
33+
34+
# Propagator Model 中的 Lattice
35+
36+
论文中有 Number、Interval、Belief、BeliefSystem 四种 Lattice。
37+
38+
其中:
39+
40+
- Number 是平凡的。
41+
- Interval 可以看作是一个 primitive lattice。
42+
- Belief 和 BeliefSystem 不是简单的 record lattice,
43+
但是可以看成是以 record lattice 为基础来定义的,
44+
就像是以 free group 为基础来定义 presentation of a group。
45+
46+
具体地说:
47+
48+
- Belief 的结构是 {}
49+
50+
- BeliefSystem 的结构是 `Record<Set, Belief>`
51+
52+
用类似 structural subtyping 的方式来统一理解所有 lattice
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
title: SolidJS and Propagator Model
3+
date: 2024-09-16
4+
---
5+
6+
solidjs 很明显就是一个 propagator model,
7+
可以理解为 cell 保存的东西是 history -- time 到 value 的 k-v-map,
8+
在前端 view 组件中显示的,只是 history 中最新的 entry。
9+
10+
下面的描述和 inet 中用表层语言来构造计算模型的对象类似:
11+
12+
> Components have a lifecycle that defines how they are created,
13+
> updated, and destroyed. A Solid component's lifecycle is different
14+
> from other frameworks, as it is tied to the concept of reactivity.
15+
16+
> Where frameworks may re-run components on every state change, a
17+
> Solid component's lifecycle is tied to its initial run. What this
18+
> means is that a Solid component is only run once, when it is first
19+
> rendered into the DOM. After that, the component is not re-run, even
20+
> if the application's state changes.
21+
22+
> When the Solid component renders, it sets up a reactive system that
23+
> monitors for state changes. When a state change occurs, the
24+
> component will update the relevant areas without re-running the
25+
> entire component. By bypassing the full component lifecycle on
26+
> every state change, Solid has a more predictable behavior compared
27+
> to frameworks that re-run functions on every update.
28+
29+
但是这里的 "re-run functions on every update"
30+
还是 expression 思维,或者说是 functional 思维。

src/belief-system/assimilateBelief.ts

+3
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@ export function assimilateBelief<A>(
1515
// whether the information contained in the new belief is deducible
1616
// from that in some beliefs already in the belief system. If so, we
1717
// can just throw the new one away.
18+
1819
if (base.beliefs.some((oldBelief) => isStrongerBelief(oldBelief, belief))) {
1920
return base
2021
}
2122

2223
// Conversely, if the information in any existing belief is
2324
// deducible from the information in the new one, we can throw those
2425
// existing ones away.
26+
2527
// 注意,对于偏序关系来说,
2628
// not(lteq(x, y)) 不等于 lteq(y, x),
2729
// 前者还包含了偏序关系中不可比较的情况。
30+
2831
const strongerOldBeliefs = base.beliefs.filter(
2932
(oldBelief) => !isStrongerBelief(belief, oldBelief),
3033
)

src/belief-system/strongestBelief.ts renamed to src/belief-system/beliefMergeManyStillBelieved.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { isBeliefBelieved } from "./isBeliefBelieved.js"
99
// 注意,这里的 "most informative" 又是就 merge 而言的了,
1010
// 别忘了 merge 所定义的 implies 与 isStronger 不同。
1111

12-
export function strongestBelief<A>(
12+
export function beliefMergeManyStillBelieved<A>(
1313
beliefs: Array<Belief<A>>,
1414
): Belief<A> | Nothing {
1515
const stillBelievedBeliefs = beliefs.filter(isBeliefBelieved)

src/belief-system/beliefSystemMerge.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import { type MergeConflict } from "../merge-conflict/index.js"
22
import { assimilateBelief } from "./assimilateBelief.js"
33
import { assimilateBeliefSystem } from "./assimilateBeliefSystem.js"
4+
import { beliefMergeManyStillBelieved } from "./beliefMergeManyStillBelieved.js"
45
import { BeliefSystem } from "./BeliefSystem.js"
5-
import { strongestBelief } from "./strongestBelief.js"
66

77
// Asking the belief system to deduce all the consequences of all its
88
// beliefs all the time is perhaps a bad idea, so when we merge belief
@@ -15,6 +15,6 @@ export function beliefSystemMerge<A, B>(
1515
increment: BeliefSystem<B>,
1616
): BeliefSystem<A | B> | MergeConflict {
1717
const candidate = assimilateBeliefSystem(content, increment)
18-
const consequence = strongestBelief(candidate.beliefs)
18+
const consequence = beliefMergeManyStillBelieved(candidate.beliefs)
1919
return assimilateBelief(candidate, consequence)
2020
}

src/belief-system/beliefSystemQuery.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { type Belief } from "../belief/index.js"
22
import type { Nothing } from "../nothing/Nothing.js"
33
import type { BeliefSystem } from "./BeliefSystem.js"
44
import { assimilateBelief } from "./assimilateBelief.js"
5-
import { strongestBelief } from "./strongestBelief.js"
5+
import { beliefMergeManyStillBelieved } from "./beliefMergeManyStillBelieved.js"
66

77
export function beliefSystemQuery<A>(
88
beliefSystem: BeliefSystem<A>,
99
): Belief<A> | Nothing {
10-
const answer = strongestBelief(beliefSystem.beliefs)
10+
const answer = beliefMergeManyStillBelieved(beliefSystem.beliefs)
1111
const betterBeliefSystem = assimilateBelief(beliefSystem, answer)
1212
if (beliefSystem !== betterBeliefSystem) {
1313
beliefSystem.beliefs = betterBeliefSystem.beliefs

src/belief/beliefMerge.ts

+12-6
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,27 @@ export function beliefMerge<A>(
3333
// (4) | -- a 与 b 不可比较
3434

3535
if (mergedValue === content.value && mergedValue === increment.value) {
36-
// 当 content.value 与 increment.value 等价时,
37-
// 取 reasons 更小的,又当 reasons 一样大时,取 content。
36+
// - 当 content.value 与 increment.value 相等时,取 reasons 更小的;
37+
// - 当 reasons 也相等时,取 content。
38+
3839
// 也就是说,当 content.value 与 increment.value 等价时,
3940
// 只有当 increment.reasons 真的比 content.reasons 小,才取 increment。
41+
42+
// 注意,这种取 subset 的行为等价于取 intersection,
43+
// 与下面取 union 的行为,在 lattice 的意义上是相互对偶的:
44+
// - 在 value 相等时用 intersection,就是用 set lattice。
45+
// - 在 value 可比较时,直接取较小 value 的 reasons。
46+
// - 在不可比较时用 union,就是用 dual set lattice。
47+
// 和 dependent type 类似,这里是 dependent record,
48+
// 即后项所取的 lattice 种类,取决于前项的值是否相等。
49+
4050
if (setIsSubsetOf(content.reasons, increment.reasons)) {
4151
return content
4252
} else {
4353
return increment
4454
}
4555
}
4656

47-
// if (isMergeConflict(mergedValue)) {
48-
// console.log({ who: "beliefMerge", increment, content })
49-
// }
50-
5157
if (mergedValue === increment.value) {
5258
return increment
5359
}

0 commit comments

Comments
 (0)