Skip to main content

tensorlogic_adapters/
compiler_integration.rs

1//! Integration utilities for tensorlogic-compiler.
2//!
3//! This module provides utilities for exporting SymbolTable data to
4//! tensorlogic-compiler's CompilerContext and for bidirectional synchronization.
5
6use anyhow::Result;
7use std::collections::HashMap;
8
9use crate::{DomainHierarchy, DomainInfo, PredicateConstraints, PredicateInfo, SymbolTable};
10
11/// Export utilities for compiler integration.
12pub struct CompilerExport;
13
14impl CompilerExport {
15    /// Export domain information as a simple map for compiler consumption.
16    ///
17    /// This returns a HashMap that maps domain names to their cardinalities,
18    /// suitable for direct use in compiler contexts.
19    ///
20    /// # Example
21    ///
22    /// ```rust
23    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, CompilerExport};
24    ///
25    /// let mut table = SymbolTable::new();
26    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
27    /// table.add_domain(DomainInfo::new("Location", 50)).unwrap();
28    ///
29    /// let domain_map = CompilerExport::export_domains(&table);
30    /// assert_eq!(domain_map.get("Person"), Some(&100));
31    /// assert_eq!(domain_map.get("Location"), Some(&50));
32    /// ```
33    pub fn export_domains(table: &SymbolTable) -> HashMap<String, usize> {
34        table
35            .domains
36            .iter()
37            .map(|(name, info)| (name.clone(), info.cardinality))
38            .collect()
39    }
40
41    /// Export predicate signatures for type checking.
42    ///
43    /// Returns a HashMap mapping predicate names to their argument domain lists.
44    ///
45    /// # Example
46    ///
47    /// ```rust
48    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, PredicateInfo, CompilerExport};
49    ///
50    /// let mut table = SymbolTable::new();
51    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
52    /// table.add_predicate(PredicateInfo::new(
53    ///     "knows",
54    ///     vec!["Person".to_string(), "Person".to_string()]
55    /// )).unwrap();
56    ///
57    /// let signatures = CompilerExport::export_predicate_signatures(&table);
58    /// assert_eq!(signatures.get("knows"), Some(&vec!["Person".to_string(), "Person".to_string()]));
59    /// ```
60    pub fn export_predicate_signatures(table: &SymbolTable) -> HashMap<String, Vec<String>> {
61        table
62            .predicates
63            .iter()
64            .map(|(name, info)| (name.clone(), info.arg_domains.clone()))
65            .collect()
66    }
67
68    /// Export variable bindings for scope analysis.
69    ///
70    /// Returns a HashMap mapping variable names to their domain types.
71    ///
72    /// # Example
73    ///
74    /// ```rust
75    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, CompilerExport};
76    ///
77    /// let mut table = SymbolTable::new();
78    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
79    /// table.bind_variable("x", "Person").unwrap();
80    /// table.bind_variable("y", "Person").unwrap();
81    ///
82    /// let bindings = CompilerExport::export_variable_bindings(&table);
83    /// assert_eq!(bindings.get("x"), Some(&"Person".to_string()));
84    /// assert_eq!(bindings.get("y"), Some(&"Person".to_string()));
85    /// ```
86    pub fn export_variable_bindings(table: &SymbolTable) -> HashMap<String, String> {
87        table
88            .variables
89            .iter()
90            .map(|(var, domain)| (var.clone(), domain.clone()))
91            .collect()
92    }
93
94    /// Create a complete export bundle for compiler initialization.
95    ///
96    /// Returns all three maps (domains, signatures, bindings) in a single structure.
97    pub fn export_all(table: &SymbolTable) -> CompilerExportBundle {
98        CompilerExportBundle {
99            domains: Self::export_domains(table),
100            predicate_signatures: Self::export_predicate_signatures(table),
101            variable_bindings: Self::export_variable_bindings(table),
102        }
103    }
104}
105
106/// Complete export bundle for compiler integration.
107///
108/// This structure contains all information needed to initialize a compiler context
109/// from a symbol table.
110#[derive(Clone, Debug)]
111pub struct CompilerExportBundle {
112    /// Domain names mapped to cardinalities.
113    pub domains: HashMap<String, usize>,
114    /// Predicate names mapped to argument domain lists.
115    pub predicate_signatures: HashMap<String, Vec<String>>,
116    /// Variable names mapped to domain types.
117    pub variable_bindings: HashMap<String, String>,
118}
119
120impl CompilerExportBundle {
121    /// Create an empty export bundle.
122    pub fn new() -> Self {
123        Self {
124            domains: HashMap::new(),
125            predicate_signatures: HashMap::new(),
126            variable_bindings: HashMap::new(),
127        }
128    }
129
130    /// Check if the bundle is empty.
131    pub fn is_empty(&self) -> bool {
132        self.domains.is_empty()
133            && self.predicate_signatures.is_empty()
134            && self.variable_bindings.is_empty()
135    }
136}
137
138impl Default for CompilerExportBundle {
139    fn default() -> Self {
140        Self::new()
141    }
142}
143
144/// Import utilities for reverse synchronization.
145pub struct CompilerImport;
146
147impl CompilerImport {
148    /// Import domain information from a compiler context back into a symbol table.
149    ///
150    /// This is useful for synchronizing state after compilation.
151    ///
152    /// # Example
153    ///
154    /// ```rust
155    /// use tensorlogic_adapters::{SymbolTable, CompilerImport};
156    /// use std::collections::HashMap;
157    ///
158    /// let mut domains = HashMap::new();
159    /// domains.insert("Person".to_string(), 100);
160    /// domains.insert("Location".to_string(), 50);
161    ///
162    /// let mut table = SymbolTable::new();
163    /// CompilerImport::import_domains(&mut table, &domains).unwrap();
164    ///
165    /// assert!(table.get_domain("Person").is_some());
166    /// assert!(table.get_domain("Location").is_some());
167    /// ```
168    pub fn import_domains(table: &mut SymbolTable, domains: &HashMap<String, usize>) -> Result<()> {
169        for (name, cardinality) in domains {
170            table.add_domain(DomainInfo::new(name.clone(), *cardinality))?;
171        }
172        Ok(())
173    }
174
175    /// Import predicate signatures from a compiler context.
176    ///
177    /// # Example
178    ///
179    /// ```rust
180    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, CompilerImport};
181    /// use std::collections::HashMap;
182    ///
183    /// let mut table = SymbolTable::new();
184    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
185    ///
186    /// let mut signatures = HashMap::new();
187    /// signatures.insert("knows".to_string(), vec!["Person".to_string(), "Person".to_string()]);
188    ///
189    /// CompilerImport::import_predicates(&mut table, &signatures).unwrap();
190    ///
191    /// assert!(table.get_predicate("knows").is_some());
192    /// ```
193    pub fn import_predicates(
194        table: &mut SymbolTable,
195        signatures: &HashMap<String, Vec<String>>,
196    ) -> Result<()> {
197        for (name, arg_domains) in signatures {
198            table.add_predicate(PredicateInfo::new(name.clone(), arg_domains.clone()))?;
199        }
200        Ok(())
201    }
202
203    /// Import variable bindings from a compiler context.
204    ///
205    /// # Example
206    ///
207    /// ```rust
208    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, CompilerImport};
209    /// use std::collections::HashMap;
210    ///
211    /// let mut table = SymbolTable::new();
212    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
213    ///
214    /// let mut bindings = HashMap::new();
215    /// bindings.insert("x".to_string(), "Person".to_string());
216    /// bindings.insert("y".to_string(), "Person".to_string());
217    ///
218    /// CompilerImport::import_variables(&mut table, &bindings).unwrap();
219    ///
220    /// assert_eq!(table.get_variable_domain("x"), Some("Person"));
221    /// assert_eq!(table.get_variable_domain("y"), Some("Person"));
222    /// ```
223    pub fn import_variables(
224        table: &mut SymbolTable,
225        bindings: &HashMap<String, String>,
226    ) -> Result<()> {
227        for (var, domain) in bindings {
228            table.bind_variable(var, domain)?;
229        }
230        Ok(())
231    }
232
233    /// Import a complete bundle into a symbol table.
234    pub fn import_all(table: &mut SymbolTable, bundle: &CompilerExportBundle) -> Result<()> {
235        Self::import_domains(table, &bundle.domains)?;
236        Self::import_predicates(table, &bundle.predicate_signatures)?;
237        Self::import_variables(table, &bundle.variable_bindings)?;
238        Ok(())
239    }
240}
241
242/// Bidirectional synchronization utilities.
243pub struct SymbolTableSync;
244
245impl SymbolTableSync {
246    /// Synchronize a symbol table with compiler data, merging information.
247    ///
248    /// This performs a two-way sync:
249    /// 1. Exports current symbol table state
250    /// 2. Imports compiler context data
251    /// 3. Returns the merged export bundle
252    pub fn sync_with_compiler(
253        table: &mut SymbolTable,
254        compiler_bundle: &CompilerExportBundle,
255    ) -> Result<CompilerExportBundle> {
256        // First, import compiler data into the table
257        CompilerImport::import_all(table, compiler_bundle)?;
258
259        // Then, export the merged state
260        Ok(CompilerExport::export_all(table))
261    }
262
263    /// Validate that a compiler bundle is compatible with a symbol table.
264    ///
265    /// Checks that all referenced domains exist.
266    pub fn validate_bundle(
267        table: &SymbolTable,
268        bundle: &CompilerExportBundle,
269    ) -> Result<ValidationResult> {
270        let mut errors = Vec::new();
271        let mut warnings = Vec::new();
272
273        // Check predicate signatures reference existing domains
274        for (pred_name, arg_domains) in &bundle.predicate_signatures {
275            for domain in arg_domains {
276                if !table.domains.contains_key(domain) && !bundle.domains.contains_key(domain) {
277                    errors.push(format!(
278                        "Predicate '{}' references unknown domain '{}'",
279                        pred_name, domain
280                    ));
281                }
282            }
283        }
284
285        // Check variable bindings reference existing domains
286        for (var_name, domain) in &bundle.variable_bindings {
287            if !table.domains.contains_key(domain) && !bundle.domains.contains_key(domain) {
288                errors.push(format!(
289                    "Variable '{}' references unknown domain '{}'",
290                    var_name, domain
291                ));
292            }
293        }
294
295        // Warn about unused domains
296        for domain_name in bundle.domains.keys() {
297            let used_in_predicates = bundle
298                .predicate_signatures
299                .values()
300                .any(|args| args.contains(domain_name));
301            let used_in_variables = bundle.variable_bindings.values().any(|d| d == domain_name);
302
303            if !used_in_predicates && !used_in_variables {
304                warnings.push(format!(
305                    "Domain '{}' is defined but never used",
306                    domain_name
307                ));
308            }
309        }
310
311        Ok(ValidationResult { errors, warnings })
312    }
313}
314
315/// Result of bundle validation.
316#[derive(Clone, Debug)]
317pub struct ValidationResult {
318    /// Validation errors (must be empty for valid bundles).
319    pub errors: Vec<String>,
320    /// Validation warnings (non-critical issues).
321    pub warnings: Vec<String>,
322}
323
324impl ValidationResult {
325    /// Check if validation passed (no errors).
326    pub fn is_valid(&self) -> bool {
327        self.errors.is_empty()
328    }
329}
330
331#[cfg(test)]
332mod tests {
333    use super::*;
334
335    #[test]
336    fn test_export_domains() {
337        let mut table = SymbolTable::new();
338        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
339        table.add_domain(DomainInfo::new("Location", 50)).unwrap();
340
341        let domains = CompilerExport::export_domains(&table);
342        assert_eq!(domains.get("Person"), Some(&100));
343        assert_eq!(domains.get("Location"), Some(&50));
344    }
345
346    #[test]
347    fn test_export_predicate_signatures() {
348        let mut table = SymbolTable::new();
349        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
350        table
351            .add_predicate(PredicateInfo::new(
352                "knows",
353                vec!["Person".to_string(), "Person".to_string()],
354            ))
355            .unwrap();
356
357        let signatures = CompilerExport::export_predicate_signatures(&table);
358        assert_eq!(
359            signatures.get("knows"),
360            Some(&vec!["Person".to_string(), "Person".to_string()])
361        );
362    }
363
364    #[test]
365    fn test_export_all() {
366        let mut table = SymbolTable::new();
367        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
368        table
369            .add_predicate(PredicateInfo::new("knows", vec!["Person".to_string()]))
370            .unwrap();
371        table.bind_variable("x", "Person").unwrap();
372
373        let bundle = CompilerExport::export_all(&table);
374        assert_eq!(bundle.domains.len(), 1);
375        assert_eq!(bundle.predicate_signatures.len(), 1);
376        assert_eq!(bundle.variable_bindings.len(), 1);
377    }
378
379    #[test]
380    fn test_import_domains() {
381        let mut domains = HashMap::new();
382        domains.insert("Person".to_string(), 100);
383
384        let mut table = SymbolTable::new();
385        CompilerImport::import_domains(&mut table, &domains).unwrap();
386
387        assert!(table.get_domain("Person").is_some());
388    }
389
390    #[test]
391    fn test_import_predicates() {
392        let mut table = SymbolTable::new();
393        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
394
395        let mut signatures = HashMap::new();
396        signatures.insert("knows".to_string(), vec!["Person".to_string()]);
397
398        CompilerImport::import_predicates(&mut table, &signatures).unwrap();
399        assert!(table.get_predicate("knows").is_some());
400    }
401
402    #[test]
403    fn test_validation_invalid_domain_reference() {
404        let table = SymbolTable::new();
405        let mut bundle = CompilerExportBundle::new();
406        bundle
407            .predicate_signatures
408            .insert("knows".to_string(), vec!["UnknownDomain".to_string()]);
409
410        let result = SymbolTableSync::validate_bundle(&table, &bundle).unwrap();
411        assert!(!result.is_valid());
412        assert!(!result.errors.is_empty());
413    }
414
415    #[test]
416    fn test_validation_unused_domain_warning() {
417        let table = SymbolTable::new();
418        let mut bundle = CompilerExportBundle::new();
419        bundle.domains.insert("UnusedDomain".to_string(), 100);
420
421        let result = SymbolTableSync::validate_bundle(&table, &bundle).unwrap();
422        assert!(result.is_valid()); // Still valid, just has warnings
423        assert!(!result.warnings.is_empty());
424    }
425
426    #[test]
427    fn test_sync_with_compiler() {
428        let mut table = SymbolTable::new();
429        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
430
431        let mut bundle = CompilerExportBundle::new();
432        bundle.domains.insert("Location".to_string(), 50);
433
434        let result = SymbolTableSync::sync_with_compiler(&mut table, &bundle).unwrap();
435
436        // Table should now have both domains
437        assert!(table.get_domain("Person").is_some());
438        assert!(table.get_domain("Location").is_some());
439
440        // Result should include both
441        assert_eq!(result.domains.len(), 2);
442    }
443}
444
445/// Advanced export utilities for compiler integration with type systems.
446///
447/// This extends the basic CompilerExport with support for advanced type system
448/// features including refinement types, dependent types, linear types, and effects.
449pub struct CompilerExportAdvanced;
450
451impl CompilerExportAdvanced {
452    /// Export domain hierarchy information for subtype checking.
453    ///
454    /// Returns the complete subtype relationships from the hierarchy.
455    ///
456    /// # Example
457    ///
458    /// ```rust
459    /// use tensorlogic_adapters::{DomainHierarchy, CompilerExportAdvanced};
460    ///
461    /// let mut hierarchy = DomainHierarchy::new();
462    /// hierarchy.add_subtype("Student", "Person");
463    /// hierarchy.add_subtype("Person", "Agent");
464    ///
465    /// let relationships = CompilerExportAdvanced::export_hierarchy(&hierarchy);
466    /// assert!(relationships.contains_key("Student"));
467    /// ```
468    pub fn export_hierarchy(hierarchy: &DomainHierarchy) -> HashMap<String, Vec<String>> {
469        let mut result = HashMap::new();
470
471        for domain in hierarchy.all_domains() {
472            // Get all ancestors (transitive closure of parent relationships)
473            let ancestors = hierarchy.get_ancestors(&domain);
474            if !ancestors.is_empty() {
475                result.insert(domain, ancestors);
476            }
477        }
478
479        result
480    }
481
482    /// Export predicate constraints for validation and optimization.
483    ///
484    /// Returns a map of predicate names to their constraint specifications.
485    ///
486    /// # Example
487    ///
488    /// ```rust
489    /// use tensorlogic_adapters::{SymbolTable, DomainInfo, PredicateInfo, PredicateConstraints, CompilerExportAdvanced};
490    ///
491    /// let mut table = SymbolTable::new();
492    /// table.add_domain(DomainInfo::new("Person", 100)).unwrap();
493    ///
494    /// let mut pred = PredicateInfo::new("age", vec!["Person".to_string()]);
495    /// pred.constraints = Some(PredicateConstraints::new());
496    /// table.add_predicate(pred).unwrap();
497    ///
498    /// let constraints = CompilerExportAdvanced::export_constraints(&table);
499    /// assert!(constraints.contains_key("age"));
500    /// ```
501    pub fn export_constraints(table: &SymbolTable) -> HashMap<String, PredicateConstraints> {
502        table
503            .predicates
504            .iter()
505            .filter_map(|(name, info)| info.constraints.as_ref().map(|c| (name.clone(), c.clone())))
506            .collect()
507    }
508
509    /// Export refinement types for compile-time validation.
510    ///
511    /// Returns refinement type specifications that can be used for
512    /// static analysis and runtime validation.
513    pub fn export_refinement_types() -> HashMap<String, String> {
514        // Export built-in refinement types
515        // In a real implementation, this would be populated from a RefinementRegistry
516        let mut types = HashMap::new();
517        types.insert("PositiveInt".to_string(), "{ x: Int | x > 0 }".to_string());
518        types.insert(
519            "Probability".to_string(),
520            "{ x: Float | 0.0 <= x <= 1.0 }".to_string(),
521        );
522        types.insert(
523            "NonZeroFloat".to_string(),
524            "{ x: Float | x != 0.0 }".to_string(),
525        );
526        types
527    }
528
529    /// Export dependent type information for dimension tracking.
530    ///
531    /// Returns dependent type specifications for compile-time dimension checking.
532    pub fn export_dependent_types() -> HashMap<String, String> {
533        // Export common dependent type patterns
534        let mut types = HashMap::new();
535        types.insert("Vector".to_string(), "Vector<T, n>".to_string());
536        types.insert("Matrix".to_string(), "Matrix<T, m, n>".to_string());
537        types.insert("Tensor3D".to_string(), "Tensor<T, i, j, k>".to_string());
538        types.insert("SquareMatrix".to_string(), "Matrix<T, n, n>".to_string());
539        types
540    }
541
542    /// Export linear type resources for lifetime tracking.
543    ///
544    /// Returns linear type specifications for resource management.
545    pub fn export_linear_types() -> HashMap<String, String> {
546        // Export linear type specifications
547        let mut types = HashMap::new();
548        types.insert("GpuTensor".to_string(), "Linear".to_string());
549        types.insert("FileHandle".to_string(), "Linear".to_string());
550        types.insert("NetworkSocket".to_string(), "Linear".to_string());
551        types.insert("MutableReference".to_string(), "Affine".to_string());
552        types.insert("LogMessage".to_string(), "Relevant".to_string());
553        types
554    }
555
556    /// Export effect information for effect tracking.
557    ///
558    /// Returns effect specifications for compile-time effect checking.
559    pub fn export_effects() -> HashMap<String, Vec<String>> {
560        // Export common effect patterns
561        let mut effects = HashMap::new();
562        effects.insert("read_file".to_string(), vec!["IO".to_string()]);
563        effects.insert(
564            "allocate_gpu".to_string(),
565            vec!["GPU".to_string(), "State".to_string()],
566        );
567        effects.insert(
568            "train_model".to_string(),
569            vec!["State".to_string(), "NonDet".to_string()],
570        );
571        effects.insert(
572            "fetch_data".to_string(),
573            vec!["IO".to_string(), "Exception".to_string()],
574        );
575        effects
576    }
577
578    /// Create a complete advanced export bundle.
579    ///
580    /// Returns all advanced type system information in a single structure.
581    pub fn export_all_advanced(
582        table: &SymbolTable,
583        hierarchy: Option<&DomainHierarchy>,
584    ) -> AdvancedExportBundle {
585        AdvancedExportBundle {
586            hierarchy: hierarchy.map(Self::export_hierarchy),
587            constraints: Self::export_constraints(table),
588            refinement_types: Self::export_refinement_types(),
589            dependent_types: Self::export_dependent_types(),
590            linear_types: Self::export_linear_types(),
591            effects: Self::export_effects(),
592        }
593    }
594}
595
596/// Advanced export bundle containing type system information.
597#[derive(Clone, Debug)]
598pub struct AdvancedExportBundle {
599    /// Domain hierarchy (subtype relationships).
600    pub hierarchy: Option<HashMap<String, Vec<String>>>,
601    /// Predicate constraints.
602    pub constraints: HashMap<String, PredicateConstraints>,
603    /// Refinement type specifications.
604    pub refinement_types: HashMap<String, String>,
605    /// Dependent type specifications.
606    pub dependent_types: HashMap<String, String>,
607    /// Linear type specifications.
608    pub linear_types: HashMap<String, String>,
609    /// Effect specifications.
610    pub effects: HashMap<String, Vec<String>>,
611}
612
613impl AdvancedExportBundle {
614    /// Create an empty advanced export bundle.
615    pub fn new() -> Self {
616        Self {
617            hierarchy: None,
618            constraints: HashMap::new(),
619            refinement_types: HashMap::new(),
620            dependent_types: HashMap::new(),
621            linear_types: HashMap::new(),
622            effects: HashMap::new(),
623        }
624    }
625
626    /// Check if the bundle is empty.
627    pub fn is_empty(&self) -> bool {
628        self.hierarchy.is_none()
629            && self.constraints.is_empty()
630            && self.refinement_types.is_empty()
631            && self.dependent_types.is_empty()
632            && self.linear_types.is_empty()
633            && self.effects.is_empty()
634    }
635}
636
637impl Default for AdvancedExportBundle {
638    fn default() -> Self {
639        Self::new()
640    }
641}
642
643/// Complete compiler integration bundle combining basic and advanced exports.
644#[derive(Clone, Debug)]
645pub struct CompleteExportBundle {
646    /// Basic export bundle (domains, predicates, variables).
647    pub basic: CompilerExportBundle,
648    /// Advanced type system export bundle.
649    pub advanced: AdvancedExportBundle,
650}
651
652impl CompleteExportBundle {
653    /// Create a new complete export bundle.
654    pub fn new(basic: CompilerExportBundle, advanced: AdvancedExportBundle) -> Self {
655        Self { basic, advanced }
656    }
657
658    /// Export everything from a symbol table and hierarchy.
659    pub fn from_symbol_table(table: &SymbolTable, hierarchy: Option<&DomainHierarchy>) -> Self {
660        Self {
661            basic: CompilerExport::export_all(table),
662            advanced: CompilerExportAdvanced::export_all_advanced(table, hierarchy),
663        }
664    }
665
666    /// Check if the bundle is completely empty.
667    pub fn is_empty(&self) -> bool {
668        self.basic.is_empty() && self.advanced.is_empty()
669    }
670}
671
672#[cfg(test)]
673mod advanced_tests {
674    use super::*;
675
676    #[test]
677    fn test_export_hierarchy() {
678        let mut hierarchy = DomainHierarchy::new();
679        hierarchy.add_subtype("Student", "Person");
680        hierarchy.add_subtype("Person", "Agent");
681
682        let relationships = CompilerExportAdvanced::export_hierarchy(&hierarchy);
683
684        assert!(relationships.contains_key("Student"));
685        assert!(relationships.contains_key("Person"));
686    }
687
688    #[test]
689    fn test_export_constraints() {
690        let mut table = SymbolTable::new();
691        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
692
693        let mut pred = PredicateInfo::new("age", vec!["Person".to_string()]);
694        pred.constraints = Some(PredicateConstraints::new());
695        table.add_predicate(pred).unwrap();
696
697        let constraints = CompilerExportAdvanced::export_constraints(&table);
698        assert!(constraints.contains_key("age"));
699    }
700
701    #[test]
702    fn test_export_refinement_types() {
703        let types = CompilerExportAdvanced::export_refinement_types();
704        assert!(types.contains_key("PositiveInt"));
705        assert!(types.contains_key("Probability"));
706    }
707
708    #[test]
709    fn test_export_dependent_types() {
710        let types = CompilerExportAdvanced::export_dependent_types();
711        assert!(types.contains_key("Vector"));
712        assert!(types.contains_key("Matrix"));
713    }
714
715    #[test]
716    fn test_export_linear_types() {
717        let types = CompilerExportAdvanced::export_linear_types();
718        assert!(types.contains_key("GpuTensor"));
719        assert!(types.contains_key("FileHandle"));
720    }
721
722    #[test]
723    fn test_export_effects() {
724        let effects = CompilerExportAdvanced::export_effects();
725        assert!(effects.contains_key("read_file"));
726        assert!(effects.contains_key("allocate_gpu"));
727    }
728
729    #[test]
730    fn test_export_all_advanced() {
731        let mut table = SymbolTable::new();
732        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
733
734        let mut hierarchy = DomainHierarchy::new();
735        hierarchy.add_subtype("Student", "Person");
736
737        let bundle = CompilerExportAdvanced::export_all_advanced(&table, Some(&hierarchy));
738
739        assert!(bundle.hierarchy.is_some());
740        assert!(!bundle.refinement_types.is_empty());
741        assert!(!bundle.dependent_types.is_empty());
742    }
743
744    #[test]
745    fn test_complete_export_bundle() {
746        let mut table = SymbolTable::new();
747        table.add_domain(DomainInfo::new("Person", 100)).unwrap();
748
749        let mut hierarchy = DomainHierarchy::new();
750        hierarchy.add_subtype("Student", "Person");
751
752        let bundle = CompleteExportBundle::from_symbol_table(&table, Some(&hierarchy));
753
754        assert!(!bundle.is_empty());
755        assert_eq!(bundle.basic.domains.len(), 1);
756        assert!(bundle.advanced.hierarchy.is_some());
757    }
758
759    #[test]
760    fn test_advanced_bundle_empty() {
761        let bundle = AdvancedExportBundle::new();
762        assert!(bundle.is_empty());
763    }
764}