use tensorlogic_ir::effect_system::{
infer_operation_effects, ComputationalEffect, Effect, EffectAnnotation, EffectScheme,
EffectSet, EffectSubstitution, EffectVar, MemoryEffect, ProbabilisticEffect,
};
fn main() {
println!("=== Effect System Example ===\n");
println!("1. Basic Effect Types");
demonstrate_basic_effects();
println!();
println!("2. Effect Sets and Combinations");
demonstrate_effect_sets();
println!();
println!("3. Effect Inference for Operations");
demonstrate_effect_inference();
println!();
println!("4. Effect Polymorphism");
demonstrate_effect_polymorphism();
println!();
println!("5. Effect Compatibility Checking");
demonstrate_effect_checking();
println!();
println!("6. Effect Annotations");
demonstrate_effect_annotations();
println!();
}
fn demonstrate_basic_effects() {
let pure = Effect::Computational(ComputationalEffect::Pure);
let impure = Effect::Computational(ComputationalEffect::Impure);
let io = Effect::Computational(ComputationalEffect::IO);
println!(" Computational Effects:");
println!(" Pure: {}", pure);
println!(" Impure: {}", impure);
println!(" IO: {}", io);
let read_only = Effect::Memory(MemoryEffect::ReadOnly);
let read_write = Effect::Memory(MemoryEffect::ReadWrite);
let allocating = Effect::Memory(MemoryEffect::Allocating);
println!("\n Memory Effects:");
println!(" ReadOnly: {}", read_only);
println!(" ReadWrite: {}", read_write);
println!(" Allocating: {}", allocating);
let deterministic = Effect::Probabilistic(ProbabilisticEffect::Deterministic);
let stochastic = Effect::Probabilistic(ProbabilisticEffect::Stochastic);
println!("\n Probabilistic Effects:");
println!(" Deterministic: {}", deterministic);
println!(" Stochastic: {}", stochastic);
let differentiable = Effect::Differentiable;
let non_differentiable = Effect::NonDifferentiable;
let async_effect = Effect::Async;
let parallel = Effect::Parallel;
let custom = Effect::Custom("GPUCompute".to_string());
println!("\n Other Effects:");
println!(" Differentiable: {}", differentiable);
println!(" NonDifferentiable: {}", non_differentiable);
println!(" Async: {}", async_effect);
println!(" Parallel: {}", parallel);
println!(" Custom: {}", custom);
}
fn demonstrate_effect_sets() {
let pure_set = EffectSet::pure();
println!(" Pure effect set: {}", pure_set);
println!(" Is pure? {}", pure_set.is_pure());
println!(" Is impure? {}", pure_set.is_impure());
let diff_set = EffectSet::differentiable();
println!("\n Differentiable effect set: {}", diff_set);
println!(" Is differentiable? {}", diff_set.is_differentiable());
let stochastic_set = EffectSet::stochastic();
println!("\n Stochastic effect set: {}", stochastic_set);
println!(" Is stochastic? {}", stochastic_set.is_stochastic());
let combined = pure_set.union(&diff_set);
println!("\n Combined (pure ∪ differentiable): {}", combined);
println!(" Is pure? {}", combined.is_pure());
println!(" Is differentiable? {}", combined.is_differentiable());
let custom_set = EffectSet::new()
.with(Effect::Computational(ComputationalEffect::Pure))
.with(Effect::Differentiable)
.with(Effect::Parallel)
.with(Effect::Custom("TensorOp".to_string()));
println!("\n Custom effect set: {}", custom_set);
println!(
" Contains Pure? {}",
custom_set.contains(&Effect::Computational(ComputationalEffect::Pure))
);
println!(
" Contains Parallel? {}",
custom_set.contains(&Effect::Parallel)
);
}
fn demonstrate_effect_inference() {
let operations = vec![
"and",
"or",
"not",
"implies",
"add",
"subtract",
"multiply",
"divide",
"exists",
"forall",
"equal",
"less_than",
"sample",
"random",
"read",
"write",
"unknown_op",
];
println!(" Operation effect inference:");
for op in operations {
let effects = infer_operation_effects(op);
println!(" {:<12} -> {}", op, effects);
}
}
fn demonstrate_effect_polymorphism() {
let e1 = EffectVar::new("1");
let e2 = EffectVar::new("2");
println!(" Effect variables:");
println!(" ε1 = {}", e1);
println!(" ε2 = {}", e2);
let concrete = EffectScheme::concrete(EffectSet::pure());
println!("\n Concrete effect scheme: {}", concrete);
let variable = EffectScheme::variable("f");
println!(" Variable effect scheme: {}", variable);
let pure_scheme = EffectScheme::concrete(EffectSet::pure());
let diff_scheme = EffectScheme::concrete(EffectSet::differentiable());
let union = EffectScheme::union(pure_scheme, diff_scheme);
println!(" Union effect scheme: {}", union);
let mut subst = EffectSubstitution::new();
subst.insert(EffectVar::new("f"), EffectSet::pure());
let var_scheme = EffectScheme::variable("f");
let substituted = var_scheme.substitute(&subst);
println!("\n Substitution:");
println!(" Before: {}", var_scheme);
println!(" After: {}", substituted);
match union.evaluate(&EffectSubstitution::new()) {
Ok(effects) => {
println!("\n Evaluated union:");
println!(" Effects: {}", effects);
println!(" Is pure? {}", effects.is_pure());
println!(" Is differentiable? {}", effects.is_differentiable());
}
Err(e) => println!(" Error: {}", e),
}
}
fn demonstrate_effect_checking() {
let pure1 = EffectSet::pure();
let pure2 = EffectSet::pure().with(Effect::Differentiable);
println!(" Effect compatibility:");
println!(" pure ⊆ (pure + diff)? {}", pure1.is_subset_of(&pure2));
println!(" (pure + diff) ⊆ pure? {}", pure2.is_subset_of(&pure1));
println!(" Compatible? {}", pure1.is_compatible_with(&pure2));
let pure = EffectSet::pure();
let impure = EffectSet::impure();
println!("\n Conflicting effects:");
println!(" Pure: {}", pure);
println!(" Impure: {}", impure);
println!(" Compatible? {}", pure.is_compatible_with(&impure));
let diff = EffectSet::new().with(Effect::Differentiable);
let non_diff = EffectSet::new().with(Effect::NonDifferentiable);
println!("\n Differentiability conflict:");
println!(" Diff: {}", diff);
println!(" NonDiff: {}", non_diff);
println!(" Compatible? {}", diff.is_compatible_with(&non_diff));
let set1 = EffectSet::pure().with(Effect::Differentiable);
let set2 = EffectSet::differentiable().with(Effect::Parallel);
let intersection = set1.intersection(&set2);
println!("\n Effect intersection:");
println!(" Set1: {}", set1);
println!(" Set2: {}", set2);
println!(" Intersection: {}", intersection);
}
fn demonstrate_effect_annotations() {
let pure_ann = EffectAnnotation::pure().with_description("Pure mathematical computation");
println!(" Effect annotations:");
println!(" Pure: {}", pure_ann.scheme);
if let Some(desc) = &pure_ann.description {
println!(" Description: {}", desc);
}
let diff_ann =
EffectAnnotation::differentiable().with_description("Supports automatic differentiation");
println!("\n Differentiable: {}", diff_ann.scheme);
if let Some(desc) = &diff_ann.description {
println!(" Description: {}", desc);
}
let poly_scheme = EffectScheme::union(
EffectScheme::variable("ε"),
EffectScheme::concrete(EffectSet::differentiable()),
);
let poly_ann = EffectAnnotation::new(poly_scheme)
.with_description("Polymorphic over effect ε, but always differentiable");
println!("\n Polymorphic: {}", poly_ann.scheme);
if let Some(desc) = &poly_ann.description {
println!(" Description: {}", desc);
}
let nn_layer_effects = EffectSet::new()
.with(Effect::Computational(ComputationalEffect::Pure))
.with(Effect::Differentiable)
.with(Effect::Memory(MemoryEffect::Allocating))
.with(Effect::Parallel);
let nn_ann = EffectAnnotation::new(EffectScheme::concrete(nn_layer_effects)).with_description(
"Neural network layer: pure, differentiable, allocates memory, parallelizable",
);
println!("\n Neural Network Layer: {}", nn_ann.scheme);
if let Some(desc) = &nn_ann.description {
println!(" Description: {}", desc);
}
let sample_effects = EffectSet::new()
.with(Effect::Probabilistic(ProbabilisticEffect::Stochastic))
.with(Effect::NonDifferentiable)
.with(Effect::Memory(MemoryEffect::ReadOnly));
let sample_ann = EffectAnnotation::new(EffectScheme::concrete(sample_effects))
.with_description("Random sampling: stochastic, non-differentiable");
println!("\n Sampling Operation: {}", sample_ann.scheme);
if let Some(desc) = &sample_ann.description {
println!(" Description: {}", desc);
}
}