程式本體反演:從可執行投影重建可觀測程式本體
Program Ontology Inversion: Reconstructing Observable Program Ontology from Executable Projections
系列: 程式底空間與本體反演系列(Program Base Space and Ontology Inversion, PBSOI)
篇次: Paper 03
版本: v0.1
作者: Neo.K
機構: EveMissLab
日期: 2026-09-14
狀態: 理論方法論初稿/反演框架定義
公司: 一言諾科技有限公司
摘要
前兩篇分別提出「程式底空間」(Program Base Space, PBS)與「程式碼誘導語義圖」(Code-Induced Semantic Graph, CISG),建立了兩個前提:第一,原始碼不必等同於完整程式本體;第二,實際程式碼可以被轉換為具有型別、證據與不確定性標記的程式關係圖。本文進一步處理整個系列的核心逆問題:若程式碼是一種投影,我們究竟能從投影反向恢復多少程式本體?
本文正式提出「程式本體反演」(Program Ontology Inversion, POI),定義反演映射:
ρL:CL→P∗
其中 CL 是語言 L 下的程式碼, P∗ 是理想或權威程式本體, P∗ 則是由分析器在有限觀測條件下重建出的本體近似。本文主張,程式本體反演不是反編譯、程式摘要或自然語言解說,而是一個受可觀測性、證據來源、分析模型與語言動態性限制的結構重建問題。
本文建立四類觀測來源:靜態觀測、動態觀測、歷史觀測與外部契約觀測;提出多通道反演模型、可觀測本體、不可識別等價類、反演覆蓋向量、反演誤差向量與證據格。本文指出:單一程式碼表面通常不能唯一決定完整程式本體,因此程式本體反演在一般情況下不是單值逆函數,而是一個受證據約束的候選本體收斂過程。
本文最後提出一個保守原則:反演系統的價值不在於「猜得像」,而在於能明確區分何者已觀測、何者被強推論、何者僅弱推論、何者仍不可判定。只有在此條件下,CISG、程式底空間、跨語言正規化、結構缺陷檢測、功能 motif 與三圖一致性分析才可能共享同一個可信的程式知識層。
本文的核心命題是:
程式本體反演不是把程式碼重新說明一次,而是把可觀測程式事實從特定語言表徵中解耦,重建成可驗證、可比較且保留未知性的結構。
關鍵詞
程式本體反演、Program Ontology Inversion、POI、程式底空間、CISG、可觀測性、不可識別性、靜態分析、動態分析、語義重建、反演誤差、證據融合、程式知識圖、程式理解
一、問題的提出
1.1 從正向投影到逆向問題
假設存在某個程式本體:
P∗
而一種程式語言 L 提供投影:
πL:P∗→CL
則程式碼 CL 可以被視為:
CL=πL(P∗)
前述模型首先帶來一個直接的逆問題:
已知 CL, 能否恢復 P∗?
最直觀的寫法是:
πL−1(CL)
但這個表示在一般情況下過強。
因為 πL 通常不是雙射。
不同的本體狀態可能投影成相同或近似相同的程式碼表面;同一份程式碼在不同 runtime、configuration、dependency version 與外部環境下,也可能形成不同實際行為。
因此本文不假設:
ρL=πL−1
而定義一個更保守的反演映射:
ρL:CL→P∗
其中:
P∗
只代表在目前觀測條件下可支持的本體近似。
1.2 反演問題的核心不是「能不能理解程式碼」
程式碼理解早已有:
- parser;
- compiler;
- decompiler;
- static analyzer;
- debugger;
- profiler;
- symbolic execution;
- abstract interpretation;
- program slicing;
- model checker;
- reverse engineering。
因此,本文若只說「程式可以被分析」,沒有新的理論價值。
真正的問題是:
能否把這些彼此分散的分析結果重新視為對同一個潛在程式本體的不同觀測,並建立一個明確的反演框架?
因此,本文把問題改寫為:
O={Os,Od,Oh,Oc}
其中:
- Os:static observation;
- Od:dynamic observation;
- Oh:historical observation;
- Oc:contract / environment observation。
反演不再只依賴單一 source:
ρL(CL)
而可以寫為:
ρ(Os,Od,Oh,Oc)→P∗
這使「程式理解」從單次解析問題,變成多觀測源的本體重建問題。
二、反演對象:到底要恢復什麼
2.1 三種不同的「程式」
本文首先區分:
Pintended
Pimplemented
Prealized
其中:
意圖程式
Pintended
表示作者、團隊、需求或規格希望程式成為什麼。
實作程式
Pimplemented
表示現有 source/binary 所編碼出的結構。
實現程式
Prealized
表示程式在具體環境與輸入下真正發生的行為。
一般而言:
Pintended=Pimplemented=Prealized
並不罕見。
因此,僅從 source code 進行反演時,合理目標首先是:
Pimplemented
而不是:
Pintended
2.2 程式本體的工作定義
本文將一個工作性程式本體表示為:
P=(V,R,S,T,F,B,K,H)
其中:
- V:實體與操作;
- R:關係;
- S:狀態;
- T:轉換規則;
- F:效果;
- B:內外部邊界;
- K:約束與契約;
- H:版本與歷史關係。
這不是宣稱所有程式哲學上都必須服從此八元組,而是提供一個可供反演系統操作的最小統一容器。
三、程式本體反演不是什麼
3.1 不是反編譯
反編譯常處理:
Binary→Higher-Level Code
其目標通常是生成可讀或近似原始的程式表示。
POI 則是:
Any Executable Projection→Ontology Approximation
因此:
Decompiler Output
可以成為 POI 的一種輸入,但不是最終目標。
3.2 不是程式摘要
摘要通常為:
C→N
其中 N 是自然語言。
POI 則要求:
C→G
其中 G 必須是:
- 可計算;
- 可追溯;
- 可比較;
- 保留未知;
- 可由其他投影再次使用。
自然語言可以由 G 生成:
G→N
但不應反過來以 N 取代 G。
3.3 不是猜作者意圖
任何從程式碼直接推斷:
作者是為了效能才這樣寫。
若缺乏 commit、issue、spec 或其他證據,都不能被標記為 implementation fact。
因此:
IntentInference=OntologyObservation
四、四種觀測來源
4.1 靜態觀測
定義:
Os(C)
可包含:
- AST;
- symbol table;
- type relation;
- CFG;
- call graph;
- data flow;
- SSA;
- alias / points-to;
- effect hints;
- dependency;
- exception structure。
靜態觀測的優勢是:
- 可重現;
- 可批次;
- 不需要執行不可信程式;
- 可覆蓋未被測試走到的分支。
但它不能保證:
Os=Prealized
4.2 動態觀測
定義某次執行軌跡:
τi=(e1,e2,…,en)
多次執行得到:
Od={τ1,τ2,…,τm}
可以觀察:
- 真正發生的 call;
- 真正 branch;
- concrete type;
- allocation;
- lock;
- I/O;
- latency;
- exception;
- runtime dispatch;
- external boundary。
動態觀測的限制是:
not observed⇒impossible
也就是:
沒跑到,不等於不存在。
4.3 歷史觀測
定義 revision sequence:
H=(Pr1,Pr2,…,Prn)
歷史資訊可以補充:
- 某關係何時出現;
- 某節點是否穩定;
- 某功能是否被拆分;
- 某 boundary 是否逐步形成;
- 某 relation 是否只是短期過渡。
因此:
Oh
不是用 commit message 猜真相,而是比較:
GC(ri)→GC(ri+1)
的實際結構差分。
4.4 契約與環境觀測
定義:
Oc
可包括:
- type contract;
- API schema;
- test assertion;
- formal specification;
- database schema;
- protocol;
- permission policy;
- configuration constraints。
這些資訊有時比 source code 更直接描述:
K
即程式約束。
但契約同樣不能自動等同於實作事實。
因此:
Oc=Os
而應保持為不同證據通道。
五、多通道反演模型
5.1 基本形式
定義:
O(P)=(Os(P),Od(P),Oh(P),Oc(P))
反演系統:
ρ:O(P)→P
5.2 證據融合
對候選結構 x,定義證據集合:
E(x)={es,ed,eh,ec}
其中可能有些為空。
例如:
es=∅
但:
ed=∅
表示某 static edge 已被觀測,但目前沒有 runtime trace 支持或反駁。
因此不應寫成:
ed=∅⇒x=false
5.3 證據格
本文提出一個簡化的證據偏序:
unresolved≺weakly inferred≺strongly inferred≺observed
但不同來源之間不是簡單線性排序。
例如:
static observed
與:
dynamic observed
支持的是不同命題。
更合理的是保存向量:
q(x)=(qs,qd,qh,qc)
而不是壓成單一分數。
六、不可識別性
6.1 一般情況下反演不唯一
假設:
πL(P1)=πL(P2)=C
但:
P1=P2
則由 C 無法唯一判斷原始本體。
因此定義:
[P]C={Pi∣πL(Pi)=C}
這是一個與觀測 C 相容的本體候選等價類。
所以一般情況下:
ρ(C)
更合理的數學型態可能是:
ρ(C)→P(P)
也就是候選集合,而不是單一結果。
6.2 工程上為何仍可得到單一圖
實作系統仍然可以輸出:
P
但它應同時保存:
U
表示 unresolved / ambiguous structure。
所以:
ρ(C)=(P,U)
而不是假裝:
U=∅
6.3 不可識別不等於不可分析
這一點很重要。
即使:
P1=P2
無法區分,仍可能存在共同部分:
I(P1)=I(P2)
因此反演的合理目標不是永遠恢復全部:
P∗
而是恢復所有候選都共同支持的:
Pstable
可寫成:
Pstable=Pi∈[P]C⋂I(Pi)
這提供一種保守本體重建方式。
七、反演完備度
7.1 單一百分比不足
若只給:
κρ=0.82
其實很難知道到底缺什麼。
因此本文提出反演覆蓋向量:
Kρ=(kV,kR,kS,kT,kF,kB,kK,kH)
對應:
- 節點;
- 關係;
- 狀態;
- 轉換;
- 效果;
- 邊界;
- 契約;
- 歷史。
7.2 相對覆蓋率
若存在外部驗證集:
Pref
則可以定義:
kR=∣Rref∣∣Rreconstructed∩Rref∣
但現實中完整 Pref 通常不存在。
因此實際工程更常只能計算:
- supported coverage;
- parser coverage;
- trace coverage;
- test coverage;
- resolved-target ratio;
- evidence-backed ratio。
也就是代理指標。
7.3 可觀測覆蓋與本體覆蓋必須分開
定義:
Kobs
表示目前觀測工具能碰到的範圍。
而:
Kont
表示整個程式本體的真實覆蓋。
通常:
Kobs≥Kont
不能由已觀測部分直接推定整體本體已被完整覆蓋。
八、反演誤差
8.1 錯誤不只一種
定義反演誤差向量:
ερ=(εmiss,εfalse,εtype,εresolution,εsemantic,εprovenance)
分別表示:
- 漏掉真實節點/邊;
- 產生不存在的節點/邊;
- 型別錯誤;
- target resolution 錯誤;
- 語義分類錯誤;
- provenance 錯誤。
8.2 最危險的不是漏掉,而是捏造
對保守反演系統而言:
εfalse
通常應比:
εmiss
受到更嚴格控制。
原因是:
漏掉一條邊會降低完備度;捏造一條邊則會污染後續所有依賴它的推理。
因此可以採用:
λfalse>λmiss
的損失權重。
8.3 本體反演損失
概念上可定義:
Lρ=λ1εmiss+λ2εfalse+λ3εresolution+λ4εsemantic+λ5εprovenance
此式目前是方法論形式,不主張已有統一最佳權重。
九、靜態—動態閉合
9.1 靜態圖
定義:
Gs=ρs(C)
由 static analysis 得到。
9.2 動態圖
對 trace:
τ
建立:
Gd(τ)
表示實際發生的執行關係。
9.3 疊合
可定義:
Gsd=Gs⊕Gd
其中:
⊕
不是簡單 union,而是帶來源標記的證據疊合。
例如某 static call edge:
e
在 runtime 被觀測:
q(e)=(observed-static,observed-dynamic)
另一條 static edge 尚未走到:
q(e′)=(observed-static,not-yet-observed-dynamic)
不能將後者刪除。
十、歷史閉合
10.1 程式不是只有當前快照
若:
GC(t)
只是當前版本,則許多結構意義無法判斷。
例如一個孤立函式可能是:
- 剛加入尚未接線;
- 已廢棄但未刪除;
- plugin entrypoint;
- test-only utility。
歷史可以提供:
GC(t−2)→GC(t−1)→GC(t)
的變化脈絡。
10.2 時間型本體
因此程式本體可以進一步寫成:
P(t)
而歷史反演為:
ρH:{Cr1,…,Crn}→P(t)
此時「程式是什麼」不再只是某一 commit 的圖,而是:
state+transition+history
十一、來源權威與反演可信度
11.1 Source integrity
若來源本身不是已確認版本:
C?
則:
ρ(C?)
不能被標為 fully verified。
因此應先執行:
VerifySource(C,r,h)
其中:
11.2 Analyzer identity
相同 source 在不同 analyzer version 下可能得到:
G1=G2
因此反演結果必須保存:
Aid=(analyzer,version,config)
這是可重現性的必要部分。
11.3 Graph identity
可以定義:
ID(G)=H(r,Aid,N(G))
其中:
N(G)
表示 canonical serialization。
此機制可支援:
- cache;
- diff;
- history;
- reproducibility。
十二、CISG 在反演中的角色
Paper 02 定義:
GC
作為程式碼誘導語義圖。
在本文中,CISG 不等於反演過程本身,而是:
反演輸出的 canonical structural container
因此:
ρ(C)→GC
以及:
GC↪P∗
兩者可以同時成立。
CISG 主要保存:
- 程式結構;
- 關係;
- provenance;
- uncertainty。
而更完整的本體近似還可能包括:
- runtime statistics;
- contracts;
- historical persistence;
- architecture intent;
- environmental constraints。
十三、由反演導出的新問題
13.1 反演後能不能再投影
若:
CLρLG
則可以研究:
GπMCM
其中:
M
是另一種程式語言。
形成:
CL→G→CM
這將在後續跨語言論文處理。
13.2 反演後能不能直接執行
若 G 已經保存足夠控制、資料與效果語義,則可以研究:
E(G)
而不必回到原始 source。
第一輪小型 PoC 已證實,在受限語義子集中:
C→G→C→E(G)
可以成立。
13.3 反演後能不能找 Bug
若某些 Bug 對應:
F⊆Subgraph(G)
則可以建立:
D(G)→Δ
而不依賴自然語言理解。
十四、RepoLumen PoC 對反演問題的初步支持
前一輪 CISG PoC 對 RepoLumen 的 Git hash 驗證程式來源進行分析,得到:
182
個節點與:
334
條關係。
此實驗並未證明完整程式本體已被恢復。
它只支持:
實際 repository 可被自動轉換為具有來源證據的結構近似。
此外,mutation test 對四類注入錯誤成功觸發 detector,支持:
反演所得結構具有可直接計算的工程價值。
這兩點構成 POI 的最低工程基礎,但尚不足以證明跨語言本體收斂。
十五、最小反演管線
本文提出第一版 POI pipeline:
C→V→S→R→N→G→U
其中:
- V:source verification;
- S:syntax / symbol extraction;
- R:relation reconstruction;
- N:semantic normalization;
- G:CISG construction;
- U:uncertainty registration。
若加入 runtime:
G+Od→G′
若加入歷史:
G′+Oh→G′′
因此反演不是一次完成,而是可以持續收斂:
P(0)→P(1)→⋯→P(n)
十六、反演單調性
一個理想反演系統加入新證據時,不應任意破壞舊的 verified fact。
定義證據集合:
E1⊆E2
若:
x
已在 E1 下被 verified,且 E2 沒有反證,則期望:
x∈ρ(E1)⇒x∈ρ(E2)
這可以稱為證據單調性。
但若新證據產生矛盾:
enew⊥x
則系統應:
- 降級 confidence;
- 標記 conflict;
- 重新解析;
而不是靜默覆寫。
十七、反演與衝突
17.1 靜態與動態衝突
例如 static analysis 推出:
A→B
但大量 runtime trace 顯示該 target 永遠被其他 dispatch 取代。
此時不應簡單刪掉 static edge。
應保存:
Conflict(es,ed)
17.2 文件與實作衝突
若 README 宣稱:
A↛B
但 source 顯示:
A→B
則:
AuthorClaim=ImplementationObservation
兩者都應保存,但優先權不能混同。
十八、反演的 epistemic contract
本文建議 POI 系統至少輸出:
Kρ=(F,I,U,C)
其中:
- F:verified facts;
- I:inferences;
- U:unresolved;
- C:conflicts。
所以一個成熟反演器不是只回答:
這個程式是什麼?
而應回答:
我能證明它具有什麼結構、我強烈推論什麼、我仍不知道什麼、哪些證據互相衝突。
十九、可證偽條件
19.1 無法區分 observed 與 inferred
若系統不能可靠區分:
F
與:
I
則其反演結果不適合作為權威程式知識層。
19.2 新證據無法改善結果
若加入:
- runtime trace;
- history;
- contracts;
後:
P(n+1)
無法比:
P(n)
增加解析能力或降低不確定性,則多通道反演模型缺乏實證價值。
19.3 跨工具結果無法對齊
若不同 analyzer 對同一 source 產生的結果無法映射到共同 typed relation space,則 POI 作為統一層的可行性會受到重大限制。
19.4 反演只等價於既有單一 IR
若完整 POI 最終沒有超出某一現有 IR 的能力範圍,也無法額外整合 evidence、history、runtime 與 uncertainty,則「本體反演」不需要作為獨立工程概念存在。
二十、核心命題
本文提出以下八個核心命題。
命題 1:反演非逆函數命題
一般情況下:
ρL=πL−1
因為程式投影通常不可唯一逆。
命題 2:部分反演命題
合理目標是:
ρL(CL)=P∗
其中:
P∗⊆Observable(P∗)
命題 3:多觀測源命題
更完整反演應使用:
ρ(Os,Od,Oh,Oc)
而非只依賴 source syntax。
命題 4:不可識別命題
存在:
P1=P2
但:
πL(P1)=πL(P2)
因此反演必須保留候選與未知。
命題 5:保守錯誤命題
對可信反演系統:
εfalse
通常比:
εmiss
更危險。
命題 6:證據分層命題
Observed=Inferred=Claimed=Unresolved
必須在資料模型層顯式存在。
命題 7:持續收斂命題
反演可以隨證據增加形成:
P(0)→P(1)→⋯→P(n)
而不是一次性輸出。
命題 8:可再投影命題
若反演結果保存足夠語義,則理論上可以研究:
CL→P→CM
使反演結構成為跨語言轉換與新型程式編譯的中介基礎。
二十一、研究路線
Paper 04 將處理:
Bcommon
與跨語言語義正規化。
核心問題是:
Python、Rust、C、Java、WASM 或其他表示經反演後,哪些結構可以收斂到共同底空間,哪些差異必須保留為 language-specific semantics?
因此:
ρL
在 Paper 03 被建立後,下一步自然是研究不同:
ρL1,ρL2,…,ρLn
是否能共同落入:
Bcommon
二十二、結論
本文正式提出「程式本體反演」作為一個獨立研究問題。
它不是:
Code→Explanation
而是:
Executable Projection→Evidence-Grounded Observable Ontology
其核心關係為:
P∗πLCLρLP∗
但:
ρL=πL−1
而:
P∗=P∗
在一般情況下都必須被明確承認。
程式本體反演真正追求的不是「完全猜中」,而是:
最大化可驗證恢復+最小化虛構關係+顯式保存未知
因此,反演器的核心品質不應只以輸出多少資訊評估,而應以:
- 可追溯性;
- 可重現性;
- 誤差;
- 覆蓋;
- 不確定性誠實度;
- 跨來源一致性;
共同評估。
在此基礎上,程式碼才真正可以從「唯一主要工件」轉化為「可被觀測、反演與重新投影的計算表面」。
而程式理解則進一步轉化為:
對程式存在結構本身的測量問題
參考與前置理論
- Neo.K,《程式底空間:從原始碼表徵到計算關係的存在層》,PBSOI Paper 01。
- Neo.K,《程式碼誘導語義圖:由實作生成而非由設計繪製的程式節點圖》,PBSOI Paper 02。
- Neo.K,《從程式碼到意圖:程式概念的歷史轉換與後文本時代》。
- Neo.K,《多重投影程式論:原始碼不再是程式本體》。
- Neo.K,《程式語言設計風格的多軸形態空間》。
- Neo.K,《基本計算單位的歷史轉換:從指令、函數到張量、意圖與世界狀態》。
- Neo.K,《空間狀態論:異質底空間、嵌套尺度與空間改寫算子的統一方法論》。
- EveMissLab,RepoLumen / Repo Semantic Teaching Layer v0.10。
- EveMissLab,CISG RepoLumen PoC v0.1。