sim-nest 0.1.5

The SIM constellation umbrella facade: one crate that re-exports the runtime kernel, codecs, number domains, and libraries behind features.
Documentation
use std::sync::Arc;

#[cfg(feature = "numbers-complex")]
use sim_kernel::Args;
use sim_kernel::{DefaultFactory, Expr, NoopEvalPolicy, NumberLiteral, Symbol};

use crate::runtime::install_core_runtime;

use super::support::table_value;

#[cfg(feature = "numbers-f64")]
#[test]
fn number_domain_lib_exports_literal_class_and_shape_surfaces() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let domain = cx
        .resolve_number_domain(&Symbol::qualified("numbers", "f64"))
        .unwrap();
    let domain_table = domain.object().as_table(&mut cx).unwrap();
    let domain_expr = domain_table.object().as_expr(&mut cx).unwrap();
    assert!(
        cx.registry()
            .class_by_symbol(&Symbol::qualified("numbers", "f64-literal"))
            .is_some()
    );
    assert!(
        cx.registry()
            .shape_by_symbol(&Symbol::qualified("numbers/f64-literal", "instance-shape"))
            .is_some()
    );
    assert_eq!(
        table_value(&domain_expr, &Symbol::new("literal-class")),
        Some(&Expr::Symbol(Symbol::qualified("numbers", "f64-literal")))
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-f64"))]
#[test]
fn f64_domain_browse_table_includes_value_shape() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let domain = cx
        .resolve_number_domain(&Symbol::qualified("numbers", "f64"))
        .unwrap();
    let domain_table = domain.object().as_table(&mut cx).unwrap();
    let domain_expr = domain_table.object().as_expr(&mut cx).unwrap();
    assert_eq!(
        table_value(&domain_expr, &Symbol::new("value-shape")),
        Some(&Expr::Symbol(Symbol::qualified(
            "numbers/f64",
            "value-shape"
        )))
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-i64"))]
#[test]
fn i64_domain_browse_table_includes_value_shape() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let domain = cx
        .resolve_number_domain(&Symbol::qualified("numbers", "i64"))
        .unwrap();
    let domain_table = domain.object().as_table(&mut cx).unwrap();
    let domain_expr = domain_table.object().as_expr(&mut cx).unwrap();
    assert_eq!(
        table_value(&domain_expr, &Symbol::new("value-shape")),
        Some(&Expr::Symbol(Symbol::qualified(
            "numbers/i64",
            "value-shape"
        )))
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-rational"))]
#[test]
fn rational_domain_browse_table_includes_value_shape() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let domain = cx
        .resolve_number_domain(&Symbol::qualified("numbers", "rational"))
        .unwrap();
    let domain_table = domain.object().as_table(&mut cx).unwrap();
    let domain_expr = domain_table.object().as_expr(&mut cx).unwrap();
    assert_eq!(
        table_value(&domain_expr, &Symbol::new("value-shape")),
        Some(&Expr::Symbol(Symbol::qualified(
            "numbers/rational",
            "value-shape"
        )))
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-complex"))]
#[test]
fn complex_domain_browse_table_includes_value_shape() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let domain = cx
        .resolve_number_domain(&Symbol::qualified("numbers", "complex"))
        .unwrap();
    let domain_table = domain.object().as_table(&mut cx).unwrap();
    let domain_expr = domain_table.object().as_expr(&mut cx).unwrap();
    assert_eq!(
        table_value(&domain_expr, &Symbol::new("value-shape")),
        Some(&Expr::Symbol(Symbol::qualified(
            "numbers/complex",
            "value-shape"
        )))
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-f64"))]
#[test]
fn f64_literal_and_value_dispatch_match() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let left = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "f64"), "1.25".to_owned())
        .unwrap();
    let right = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "f64"), "2.5".to_owned())
        .unwrap();
    let literal = cx
        .apply_number_binary_op(
            &Symbol::qualified("math", "add"),
            NumberLiteral {
                domain: Symbol::qualified("numbers", "f64"),
                canonical: "1.25".to_owned(),
            },
            NumberLiteral {
                domain: Symbol::qualified("numbers", "f64"),
                canonical: "2.5".to_owned(),
            },
        )
        .unwrap();
    let value = cx
        .apply_value_number_binary_op(&Symbol::qualified("math", "add"), left, right)
        .unwrap();
    assert_eq!(
        literal.object().as_expr(&mut cx).unwrap(),
        value.object().as_expr(&mut cx).unwrap()
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-i64"))]
#[test]
fn i64_literal_and_value_dispatch_match() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let left = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "i64"), "4".to_owned())
        .unwrap();
    let right = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "i64"), "3".to_owned())
        .unwrap();
    let literal = cx
        .apply_number_binary_op(
            &Symbol::qualified("math", "mul"),
            NumberLiteral {
                domain: Symbol::qualified("numbers", "i64"),
                canonical: "4".to_owned(),
            },
            NumberLiteral {
                domain: Symbol::qualified("numbers", "i64"),
                canonical: "3".to_owned(),
            },
        )
        .unwrap();
    let value = cx
        .apply_value_number_binary_op(&Symbol::qualified("math", "mul"), left, right)
        .unwrap();
    assert_eq!(
        literal.object().as_expr(&mut cx).unwrap(),
        value.object().as_expr(&mut cx).unwrap()
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-rational"))]
#[test]
fn rational_literal_and_value_dispatch_match() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let left = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "rational"), "1/2".to_owned())
        .unwrap();
    let right = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "rational"), "1/3".to_owned())
        .unwrap();
    let literal = cx
        .apply_number_binary_op(
            &Symbol::qualified("math", "add"),
            NumberLiteral {
                domain: Symbol::qualified("numbers", "rational"),
                canonical: "1/2".to_owned(),
            },
            NumberLiteral {
                domain: Symbol::qualified("numbers", "rational"),
                canonical: "1/3".to_owned(),
            },
        )
        .unwrap();
    let value = cx
        .apply_value_number_binary_op(&Symbol::qualified("math", "add"), left, right)
        .unwrap();
    assert_eq!(
        literal.object().as_expr(&mut cx).unwrap(),
        value.object().as_expr(&mut cx).unwrap()
    );
}

#[cfg(all(feature = "numbers-arith", feature = "numbers-complex"))]
#[test]
fn complex_literal_and_value_dispatch_match() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let left = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "complex"), "1+2i".to_owned())
        .unwrap();
    let right = cx
        .factory()
        .number_literal(Symbol::qualified("numbers", "complex"), "3+4i".to_owned())
        .unwrap();
    let literal = cx
        .apply_number_binary_op(
            &Symbol::qualified("math", "mul"),
            NumberLiteral {
                domain: Symbol::qualified("numbers", "complex"),
                canonical: "1+2i".to_owned(),
            },
            NumberLiteral {
                domain: Symbol::qualified("numbers", "complex"),
                canonical: "3+4i".to_owned(),
            },
        )
        .unwrap();
    let value = cx
        .apply_value_number_binary_op(&Symbol::qualified("math", "mul"), left, right)
        .unwrap();
    assert_eq!(
        literal.object().as_expr(&mut cx).unwrap(),
        value.object().as_expr(&mut cx).unwrap()
    );
}

#[cfg(all(feature = "numbers-f64", feature = "numbers-complex"))]
#[test]
fn mixed_f64_and_complex_addition_promotes_to_complex() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let value = cx
        .call_function(
            &Symbol::qualified("math", "add"),
            Args::new(vec![
                cx.factory()
                    .number_literal(Symbol::qualified("numbers", "f64"), "1.5".to_owned())
                    .unwrap(),
                cx.factory()
                    .number_literal(Symbol::qualified("numbers", "complex"), "0.5+2i".to_owned())
                    .unwrap(),
            ]),
        )
        .unwrap();
    assert_eq!(
        value.object().as_expr(&mut cx).unwrap(),
        Expr::Number(NumberLiteral {
            domain: Symbol::qualified("numbers", "complex"),
            canonical: "2+2i".to_owned()
        })
    );
}

#[cfg(feature = "numbers-complex")]
#[test]
fn complex_reduction_product_is_registered() {
    let mut cx = sim_kernel::Cx::new(Arc::new(NoopEvalPolicy), Arc::new(DefaultFactory));
    install_core_runtime(&mut cx);
    let value = cx
        .call_function(
            &Symbol::qualified("math", "product"),
            Args::new(vec![
                cx.factory()
                    .number_literal(Symbol::qualified("numbers", "complex"), "1+2i".to_owned())
                    .unwrap(),
                cx.factory()
                    .number_literal(Symbol::qualified("numbers", "complex"), "3+4i".to_owned())
                    .unwrap(),
            ]),
        )
        .unwrap();
    assert_eq!(
        value.object().as_expr(&mut cx).unwrap(),
        Expr::Number(NumberLiteral {
            domain: Symbol::qualified("numbers", "complex"),
            canonical: "-5+10i".to_owned()
        })
    );
}