1717use serde:: { Deserialize , Serialize } ;
1818use std:: collections:: HashMap ;
1919
20- use crate :: core:: { Context , Goal , Hypothesis , ProofState , Term , Theorem } ;
20+ use crate :: core:: { Context , Definition , Goal , Hypothesis , ProofState , Term , Theorem } ;
2121
2222/// Kind of node in the proof graph.
2323///
@@ -63,6 +63,12 @@ pub enum EdgeKind {
6363 DependsOn ,
6464 /// Reverse of DependsOn (premise is useful for goal)
6565 UsefulFor ,
66+ /// Source has the target as its QTT multiplicity annotation
67+ HasMultiplicity ,
68+ /// Source has the target as its algebraic effect annotation
69+ HasEffect ,
70+ /// Source has the target as its modal decoration
71+ HasModality ,
6672}
6773
6874/// A single node in the proof graph.
@@ -185,18 +191,25 @@ impl ProofGraphBuilder {
185191 // Phase 2: Add hypothesis nodes from context
186192 let hyp_ids = self . add_hypotheses_from_context ( & state. context ) ;
187193
194+ // Phase 2b: Add definition nodes from context
195+ let def_ids = self . add_definitions_from_context ( & state. context ) ;
196+
188197 // Phase 3: Add premise/theorem nodes from context
189198 for theorem in & state. context . theorems {
190199 let pid = self . add_premise ( theorem) ;
191200 premise_node_ids. push ( pid) ;
192201 }
193202
194- // Phase 4: Add dependency edges from goals to hypotheses/premises
203+ // Phase 4: Add dependency edges from goals to hypotheses/definitions/ premises
195204 if let Some ( gid) = goal_node_id {
196205 for & hid in & hyp_ids {
197206 self . add_edge ( gid, hid, EdgeKind :: DependsOn , 1.0 ) ;
198207 self . add_edge ( hid, gid, EdgeKind :: UsefulFor , 1.0 ) ;
199208 }
209+ for & did in & def_ids {
210+ self . add_edge ( gid, did, EdgeKind :: DependsOn , 0.9 ) ;
211+ self . add_edge ( did, gid, EdgeKind :: UsefulFor , 0.9 ) ;
212+ }
200213 for & pid in & premise_node_ids {
201214 self . add_edge ( gid, pid, EdgeKind :: DependsOn , 0.8 ) ;
202215 self . add_edge ( pid, gid, EdgeKind :: UsefulFor , 0.8 ) ;
@@ -278,6 +291,11 @@ impl ProofGraphBuilder {
278291 self . expand_term ( body, hid, 1 ) ;
279292 }
280293
294+ // Wire type_info annotations as edges
295+ if let Some ( ref info) = hyp. type_info {
296+ self . add_type_info_edges ( hid, info) ;
297+ }
298+
281299 hid
282300 }
283301
@@ -288,11 +306,49 @@ impl ProofGraphBuilder {
288306 let label = format ! ( "{}: {}" , var. name, var. ty) ;
289307 let vid = self . add_node ( NodeKind :: Hypothesis , & label, 0 ) ;
290308 self . expand_term ( & var. ty , vid, 1 ) ;
309+
310+ // Wire type_info annotations as edges
311+ if let Some ( ref info) = var. type_info {
312+ self . add_type_info_edges ( vid, info) ;
313+ }
314+
291315 ids. push ( vid) ;
292316 }
293317 ids
294318 }
295319
320+ /// Add definition nodes from the global context.
321+ fn add_definitions_from_context ( & mut self , ctx : & Context ) -> Vec < usize > {
322+ let mut ids = Vec :: new ( ) ;
323+ for def in & ctx. definitions {
324+ let did = self . add_definition ( def) ;
325+ ids. push ( did) ;
326+ }
327+ ids
328+ }
329+
330+ /// Add a definition node.
331+ fn add_definition ( & mut self , def : & Definition ) -> usize {
332+ let label = format ! ( "{}: {}" , def. name, def. ty) ;
333+ let did = self . add_node ( NodeKind :: Hypothesis , & label, 0 ) ;
334+
335+ // Expand the definition type
336+ let type_id = self . expand_term ( & def. ty , did, 1 ) ;
337+ if let Some ( tid) = type_id {
338+ self . add_edge ( did, tid, EdgeKind :: HasType , 1.0 ) ;
339+ }
340+
341+ // Expand the definition body
342+ self . expand_term ( & def. body , did, 1 ) ;
343+
344+ // Wire type_info annotations as edges
345+ if let Some ( ref info) = def. type_info {
346+ self . add_type_info_edges ( did, info) ;
347+ }
348+
349+ did
350+ }
351+
296352 /// Add a premise (theorem/lemma) node.
297353 fn add_premise ( & mut self , theorem : & Theorem ) -> usize {
298354 let label = format ! ( "{}: {}" , theorem. name, theorem. statement) ;
@@ -456,6 +512,32 @@ impl ProofGraphBuilder {
456512 }
457513 }
458514
515+ /// Add edges from a node to represent its [`TypeInfo`] annotations.
516+ ///
517+ /// Creates labelled subterm nodes for multiplicity, effect, and modality
518+ /// decorations and connects them with the appropriate edge kind.
519+ fn add_type_info_edges ( & mut self , node_id : usize , info : & crate :: types:: TypeInfo ) {
520+ if let Some ( ref mult) = info. multiplicity {
521+ let label = format ! ( "mult:{:?}" , mult) ;
522+ let mid = self . add_node ( NodeKind :: Subterm , & label, 1 ) ;
523+ self . add_edge ( node_id, mid, EdgeKind :: HasMultiplicity , 1.0 ) ;
524+ }
525+
526+ if !info. effects . is_empty ( ) {
527+ for eff in & info. effects . effects {
528+ let label = format ! ( "effect:{:?}" , eff) ;
529+ let eid = self . add_node ( NodeKind :: Subterm , & label, 1 ) ;
530+ self . add_edge ( node_id, eid, EdgeKind :: HasEffect , 1.0 ) ;
531+ }
532+ }
533+
534+ if let Some ( ref modality) = info. modality {
535+ let label = format ! ( "modality:{:?}" , modality) ;
536+ let mid = self . add_node ( NodeKind :: Subterm , & label, 1 ) ;
537+ self . add_edge ( node_id, mid, EdgeKind :: HasModality , 1.0 ) ;
538+ }
539+ }
540+
459541 /// Add shared-structure edges between premise nodes that share constants.
460542 ///
461543 /// Two premises sharing named constants likely have semantic overlap,
0 commit comments