Skip to main content

04_compilation_strategies/
main.rs

1//! Example 04: Compilation Strategies Comparison
2//!
3//! This example demonstrates the different compilation strategies available in TensorLogic
4//! and shows how they affect the semantics of logical operations.
5//!
6//! Strategies demonstrated:
7//! - soft_differentiable: For neural network training (default)
8//! - hard_boolean: Discrete Boolean logic
9//! - fuzzy_godel: Gödel fuzzy logic
10//! - fuzzy_product: Product fuzzy logic
11//! - fuzzy_lukasiewicz: Łukasiewicz fuzzy logic
12//! - probabilistic: Probabilistic interpretation
13
14use tensorlogic_compiler::{compile_to_einsum_with_config, CompilationConfig};
15use tensorlogic_infer::TlAutodiff;
16use tensorlogic_ir::{TLExpr, Term};
17use tensorlogic_scirs_backend::{Scirs2Exec, Scirs2Tensor};
18
19fn main() {
20    let sep = "=".repeat(70);
21    println!("{}", sep);
22    println!("TensorLogic - Compilation Strategies Comparison");
23    println!("{}", sep);
24    println!();
25
26    // Create a simple logical expression: P(x) AND Q(x)
27    let p = TLExpr::pred("P", vec![Term::var("x")]);
28    let q = TLExpr::pred("Q", vec![Term::var("x")]);
29    let and_expr = TLExpr::and(p.clone(), q.clone());
30
31    // Test data: 5 different cases
32    // P values: [0.0, 0.2, 0.5, 0.8, 1.0]
33    // Q values: [1.0, 0.8, 0.5, 0.2, 0.0]
34    let p_data =
35        Scirs2Exec::from_vec(vec![0.0, 0.2, 0.5, 0.8, 1.0], vec![5]).expect("valid tensor data");
36    let q_data =
37        Scirs2Exec::from_vec(vec![1.0, 0.8, 0.5, 0.2, 0.0], vec![5]).expect("valid tensor data");
38
39    println!("Test Data:");
40    println!("  P(x): {:?}", p_data.as_slice().unwrap_or(&[]));
41    println!("  Q(x): {:?}", q_data.as_slice().unwrap_or(&[]));
42    println!();
43
44    // Test each compilation strategy
45    test_strategy(
46        "Soft Differentiable",
47        &and_expr,
48        &p_data,
49        &q_data,
50        CompilationConfig::soft_differentiable(),
51    );
52
53    test_strategy(
54        "Hard Boolean",
55        &and_expr,
56        &p_data,
57        &q_data,
58        CompilationConfig::hard_boolean(),
59    );
60
61    test_strategy(
62        "Fuzzy Gödel",
63        &and_expr,
64        &p_data,
65        &q_data,
66        CompilationConfig::fuzzy_godel(),
67    );
68
69    test_strategy(
70        "Fuzzy Product",
71        &and_expr,
72        &p_data,
73        &q_data,
74        CompilationConfig::fuzzy_product(),
75    );
76
77    test_strategy(
78        "Fuzzy Łukasiewicz",
79        &and_expr,
80        &p_data,
81        &q_data,
82        CompilationConfig::fuzzy_lukasiewicz(),
83    );
84
85    test_strategy(
86        "Probabilistic",
87        &and_expr,
88        &p_data,
89        &q_data,
90        CompilationConfig::probabilistic(),
91    );
92
93    println!();
94    let sep = "=".repeat(70);
95    println!("{}", sep);
96    println!("Analysis:");
97    println!("{}", sep);
98    println!();
99    println!("1. Soft Differentiable (Product):");
100    println!("   - Smooth, differentiable everywhere");
101    println!("   - Good for gradient-based optimization");
102    println!("   - Penalizes low values more");
103    println!();
104    println!("2. Hard Boolean (Min):");
105    println!("   - Exact Boolean semantics");
106    println!("   - Not differentiable at certain points");
107    println!("   - Returns minimum of inputs");
108    println!();
109    println!("3. Fuzzy Gödel (Min):");
110    println!("   - Same as Hard Boolean for AND");
111    println!("   - Part of Gödel fuzzy logic system");
112    println!();
113    println!("4. Fuzzy Product (Product):");
114    println!("   - Similar to Soft Differentiable");
115    println!("   - Standard product t-norm");
116    println!();
117    println!("5. Fuzzy Łukasiewicz (max(0, a+b-1)):");
118    println!("   - Different from other strategies");
119    println!("   - More conservative (lower values)");
120    println!("   - Good for certain applications");
121    println!();
122    println!("6. Probabilistic (Product, assumes independence):");
123    println!("   - Treats values as probabilities");
124    println!("   - P(A AND B) = P(A) * P(B) if independent");
125    println!();
126    let sep = "=".repeat(70);
127    println!("{}", sep);
128    println!();
129    println!("Note: This example demonstrates how different compilation strategies");
130    println!("affect the semantics of logical operations. Each strategy compiles");
131    println!("the same logical expression to different tensor operations.");
132    println!();
133    let sep = "=".repeat(70);
134    println!("{}", sep);
135    println!("Example Complete!");
136    println!("{}", sep);
137}
138
139fn test_strategy(
140    name: &str,
141    expr: &TLExpr,
142    p_data: &Scirs2Tensor,
143    q_data: &Scirs2Tensor,
144    config: CompilationConfig,
145) {
146    // Compile with the specified configuration
147    let graph = compile_to_einsum_with_config(expr, &config).expect("compilation should succeed");
148
149    let mut executor = Scirs2Exec::new();
150
151    // Add input tensors
152    if !graph.tensors.is_empty() {
153        executor.add_tensor(graph.tensors[0].clone(), p_data.clone());
154    }
155    if graph.tensors.len() > 1 {
156        executor.add_tensor(graph.tensors[1].clone(), q_data.clone());
157    }
158
159    // Execute
160    let result = executor.forward(&graph).expect("execution should succeed");
161
162    println!("{} Strategy:", name);
163    println!("  Result: {:?}", result.as_slice().unwrap_or(&[]));
164    println!();
165}