use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{
ErrorAccumulator, ResultAxiomRegistry, ResultEitherBridge, ResultRegistry, ValidationCollector,
};
pub fn build_result_env(env: &mut Environment) -> Result<(), String> {
let type1 = Expr::Sort(Level::succ(Level::zero()));
let type2 = Expr::Sort(Level::succ(Level::succ(Level::zero())));
let result_ty = Expr::Pi(
BinderInfo::Default,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("E"),
Box::new(type1.clone()),
Box::new(type2),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result"),
univ_params: vec![],
ty: result_ty,
})
.map_err(|e| e.to_string())?;
let ok_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("val"),
Box::new(Expr::BVar(1)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(1)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.ok"),
univ_params: vec![],
ty: ok_ty,
})
.map_err(|e| e.to_string())?;
let err_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("err"),
Box::new(Expr::BVar(0)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(1)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.err"),
univ_params: vec![],
ty: err_ty,
})
.map_err(|e| e.to_string())?;
let is_ok_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::BVar(0)),
)),
Box::new(Expr::Const(Name::str("Bool"), vec![])),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.isOk"),
univ_params: vec![],
ty: is_ok_ty,
})
.map_err(|e| e.to_string())?;
let is_err_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::BVar(0)),
)),
Box::new(Expr::Const(Name::str("Bool"), vec![])),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.isErr"),
univ_params: vec![],
ty: is_err_ty,
})
.map_err(|e| e.to_string())?;
let map_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("U"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("f"),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("_"),
Box::new(Expr::BVar(2)),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(3)),
)),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(3)),
)),
)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.map"),
univ_params: vec![],
ty: map_ty,
})
.map_err(|e| e.to_string())?;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
fn setup_env() -> Environment {
let mut env = Environment::new();
let type1 = Expr::Sort(Level::succ(Level::zero()));
env.add(Declaration::Axiom {
name: Name::str("Bool"),
univ_params: vec![],
ty: type1,
})
.expect("operation should succeed");
env
}
#[test]
fn test_build_result_env() {
let mut env = setup_env();
assert!(build_result_env(&mut env).is_ok());
assert!(env.get(&Name::str("Result")).is_some());
assert!(env.get(&Name::str("Result.ok")).is_some());
assert!(env.get(&Name::str("Result.err")).is_some());
}
#[test]
fn test_result_is_ok() {
let mut env = setup_env();
build_result_env(&mut env).expect("build_result_env should succeed");
let decl = env
.get(&Name::str("Result.isOk"))
.expect("declaration 'Result.isOk' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
#[test]
fn test_result_is_err() {
let mut env = setup_env();
build_result_env(&mut env).expect("build_result_env should succeed");
let decl = env
.get(&Name::str("Result.isErr"))
.expect("declaration 'Result.isErr' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
#[test]
fn test_result_map() {
let mut env = setup_env();
build_result_env(&mut env).expect("build_result_env should succeed");
let decl = env
.get(&Name::str("Result.map"))
.expect("declaration 'Result.map' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
}
pub fn build_result_combinators(env: &mut Environment) -> Result<(), String> {
let type1 = Expr::Sort(Level::succ(Level::zero()));
let and_then_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("U"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("f"),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("_"),
Box::new(Expr::BVar(3)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(3)),
)),
)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(3)),
)),
)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.andThen"),
univ_params: vec![],
ty: and_then_ty,
})
.map_err(|e| e.to_string())?;
let map_err_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("F"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("f"),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("_"),
Box::new(Expr::BVar(1)),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(3)),
)),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(4)),
)),
Box::new(Expr::BVar(2)),
)),
)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.mapErr"),
univ_params: vec![],
ty: map_err_ty,
})
.map_err(|e| e.to_string())?;
let get_or_else_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("default"),
Box::new(Expr::BVar(1)),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("r"),
Box::new(Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(Expr::BVar(2)),
)),
Box::new(Expr::BVar(1)),
)),
Box::new(Expr::BVar(3)),
)),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.getOrElse"),
univ_params: vec![],
ty: get_or_else_ty,
})
.map_err(|e| e.to_string())?;
Ok(())
}
pub fn build_result_theorems(env: &mut Environment) -> Result<(), String> {
let prop = Expr::Sort(Level::zero());
let type1 = Expr::Sort(Level::succ(Level::zero()));
let ok_is_ok_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("v"),
Box::new(Expr::BVar(1)),
Box::new(prop.clone()),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.ok_isOk"),
univ_params: vec![],
ty: ok_is_ok_ty,
})
.map_err(|e| e.to_string())?;
let err_is_err_ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Default,
Name::str("e"),
Box::new(Expr::BVar(0)),
Box::new(prop.clone()),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str("Result.err_isErr"),
univ_params: vec![],
ty: err_is_err_ty,
})
.map_err(|e| e.to_string())?;
Ok(())
}
pub fn count_result_decls(env: &Environment) -> usize {
let names = [
"Result",
"Result.ok",
"Result.err",
"Result.isOk",
"Result.isErr",
"Result.map",
"Result.andThen",
"Result.mapErr",
"Result.getOrElse",
"Result.ok_isOk",
"Result.err_isErr",
];
names
.iter()
.filter(|&&n| env.get(&Name::str(n)).is_some())
.count()
}
#[cfg(test)]
mod result_extended_tests {
use super::*;
fn setup_env() -> Environment {
let mut env = Environment::new();
let type1 = Expr::Sort(Level::succ(Level::zero()));
env.add(Declaration::Axiom {
name: Name::str("Bool"),
univ_params: vec![],
ty: type1,
})
.expect("operation should succeed");
build_result_env(&mut env).expect("build_result_env should succeed");
env
}
#[test]
fn test_result_and_then() {
let mut env = setup_env();
assert!(build_result_combinators(&mut env).is_ok());
assert!(env.get(&Name::str("Result.andThen")).is_some());
}
#[test]
fn test_result_map_err() {
let mut env = setup_env();
build_result_combinators(&mut env).expect("build_result_combinators should succeed");
assert!(env.get(&Name::str("Result.mapErr")).is_some());
}
#[test]
fn test_result_get_or_else() {
let mut env = setup_env();
build_result_combinators(&mut env).expect("build_result_combinators should succeed");
assert!(env.get(&Name::str("Result.getOrElse")).is_some());
}
#[test]
fn test_result_theorems() {
let mut env = setup_env();
assert!(build_result_theorems(&mut env).is_ok());
assert!(env.get(&Name::str("Result.ok_isOk")).is_some());
assert!(env.get(&Name::str("Result.err_isErr")).is_some());
}
#[test]
fn test_count_result_decls_base() {
let env = setup_env();
let count = count_result_decls(&env);
assert!(count >= 5);
}
#[test]
fn test_count_result_decls_extended() {
let mut env = setup_env();
build_result_combinators(&mut env).expect("build_result_combinators should succeed");
build_result_theorems(&mut env).expect("build_result_theorems should succeed");
let count = count_result_decls(&env);
assert!(count >= 10);
}
#[test]
fn test_result_decl_is_axiom() {
let mut env = setup_env();
build_result_combinators(&mut env).expect("build_result_combinators should succeed");
let decl = env
.get(&Name::str("Result.andThen"))
.expect("declaration 'Result.andThen' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
#[test]
fn test_result_theorem_is_axiom() {
let mut env = setup_env();
build_result_theorems(&mut env).expect("build_result_theorems should succeed");
let decl = env
.get(&Name::str("Result.ok_isOk"))
.expect("declaration 'Result.ok_isOk' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
}
pub trait WithContext<T> {
fn with_context(self, context: &str) -> std::result::Result<T, String>;
}
impl<T> WithContext<T> for std::result::Result<T, String> {
fn with_context(self, context: &str) -> std::result::Result<T, String> {
self.map_err(|e| format!("{}: {}", context, e))
}
}
pub fn build_full_result_stdlib(env: &mut Environment) -> std::result::Result<(), String> {
let type1 = Expr::Sort(Level::succ(Level::zero()));
if env.get(&Name::str("Bool")).is_none() {
env.add(Declaration::Axiom {
name: Name::str("Bool"),
univ_params: vec![],
ty: type1,
})
.map_err(|e| e.to_string())?;
}
build_result_env(env)?;
build_result_combinators(env)?;
build_result_theorems(env)?;
Ok(())
}
#[cfg(test)]
mod error_monad_tests {
use super::*;
#[test]
fn test_error_accumulator_no_errors() {
let acc = ErrorAccumulator::new();
assert!(!acc.has_errors());
assert_eq!(acc.len(), 0);
assert!(acc.into_result().is_ok());
}
#[test]
fn test_error_accumulator_with_errors() {
let mut acc = ErrorAccumulator::new();
let _v: Option<i32> = acc.try_add(Err("error 1".to_string()));
let _v2: Option<i32> = acc.try_add(Err("error 2".to_string()));
assert!(acc.has_errors());
assert_eq!(acc.len(), 2);
let result = acc.into_result();
assert!(result.is_err());
let msg = result.unwrap_err();
assert!(msg.contains("error 1"));
assert!(msg.contains("error 2"));
}
#[test]
fn test_error_accumulator_mixed() {
let mut acc = ErrorAccumulator::new();
let v1 = acc.try_add(Ok::<i32, String>(42));
let _v2: Option<i32> = acc.try_add(Err("oops".to_string()));
assert_eq!(v1, Some(42));
assert_eq!(acc.len(), 1);
}
#[test]
fn test_error_accumulator_clear() {
let mut acc = ErrorAccumulator::new();
let _: Option<i32> = acc.try_add(Err("e".to_string()));
assert!(!acc.is_empty());
acc.clear();
assert!(acc.is_empty());
}
#[test]
fn test_with_context() {
let result: std::result::Result<i32, String> = Err("not found".to_string());
let with_ctx = result.with_context("while loading file");
let msg = with_ctx.unwrap_err();
assert!(msg.contains("while loading file"));
assert!(msg.contains("not found"));
}
#[test]
fn test_with_context_ok() {
let result: std::result::Result<i32, String> = Ok(42);
let with_ctx = result.with_context("context");
assert_eq!(with_ctx.expect("with_ctx should be valid"), 42);
}
#[test]
fn test_build_full_result_stdlib() {
let mut env = Environment::new();
assert!(build_full_result_stdlib(&mut env).is_ok());
assert!(env.get(&Name::str("Result")).is_some());
assert!(env.get(&Name::str("Result.andThen")).is_some());
assert!(env.get(&Name::str("Result.ok_isOk")).is_some());
}
#[test]
fn test_build_full_result_stdlib_twice() {
let mut env = Environment::new();
let type1 = Expr::Sort(Level::succ(Level::zero()));
env.add(Declaration::Axiom {
name: Name::str("Bool"),
univ_params: vec![],
ty: type1,
})
.expect("operation should succeed");
assert!(build_full_result_stdlib(&mut env).is_ok());
}
}
pub fn mk_result_ty(t: Expr, e: Expr) -> Expr {
Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result"), vec![])),
Box::new(t),
)),
Box::new(e),
)
}
pub fn mk_result_ok(v: Expr) -> Expr {
Expr::App(
Box::new(Expr::Const(Name::str("Result.ok"), vec![])),
Box::new(v),
)
}
pub fn mk_result_err(e: Expr) -> Expr {
Expr::App(
Box::new(Expr::Const(Name::str("Result.err"), vec![])),
Box::new(e),
)
}
#[cfg(test)]
mod expr_builder_tests {
use super::*;
#[test]
fn test_mk_result_ty() {
let t = Expr::Const(Name::str("Nat"), vec![]);
let e = Expr::Const(Name::str("String"), vec![]);
let result = mk_result_ty(t, e);
assert!(matches!(result, Expr::App(_, _)));
}
#[test]
fn test_mk_result_ok() {
let v = Expr::Lit(oxilean_kernel::Literal::Nat(42));
let ok_expr = mk_result_ok(v);
assert!(matches!(ok_expr, Expr::App(_, _)));
}
#[test]
fn test_mk_result_err() {
let e = Expr::Lit(oxilean_kernel::Literal::Str("error".to_string()));
let err_expr = mk_result_err(e);
assert!(matches!(err_expr, Expr::App(_, _)));
}
}
#[allow(dead_code)]
pub fn mk_result_and_then(r: Expr, f: Expr) -> Expr {
Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result.andThen"), vec![])),
Box::new(r),
)),
Box::new(f),
)
}
#[allow(dead_code)]
pub fn mk_result_map(f: Expr, r: Expr) -> Expr {
Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result.map"), vec![])),
Box::new(f),
)),
Box::new(r),
)
}
#[allow(dead_code)]
pub fn mk_result_get_or_else(default: Expr, r: Expr) -> Expr {
Expr::App(
Box::new(Expr::App(
Box::new(Expr::Const(Name::str("Result.getOrElse"), vec![])),
Box::new(default),
)),
Box::new(r),
)
}
#[allow(dead_code)]
pub fn validate_result_env(env: &Environment) -> Vec<&'static str> {
let required = [
"Result",
"Result.ok",
"Result.err",
"Result.isOk",
"Result.isErr",
"Result.map",
];
required
.iter()
.filter(|&&n| env.get(&Name::str(n)).is_none())
.copied()
.collect()
}
#[allow(dead_code)]
pub fn build_test_result_env() -> std::result::Result<Environment, String> {
let mut env = Environment::new();
build_full_result_stdlib(&mut env)?;
Ok(env)
}
#[cfg(test)]
mod result_registry_tests {
use super::*;
#[test]
fn test_result_registry_empty() {
let r = ResultRegistry::new();
assert!(r.is_empty());
assert_eq!(r.len(), 0);
}
#[test]
fn test_result_registry_register() {
let mut r = ResultRegistry::new();
r.register("Result.ok");
r.register("Result.err");
r.register("Result.ok");
assert_eq!(r.len(), 2);
assert!(r.contains("Result.ok"));
assert!(!r.contains("Result.map"));
}
#[test]
fn test_result_registry_from_env() {
let env = build_test_result_env().expect("build_test_result_env should succeed");
let reg = ResultRegistry::from_env(&env);
assert!(reg.contains("Result"));
assert!(reg.contains("Result.ok"));
assert!(reg.contains("Result.andThen"));
}
#[test]
fn test_validate_result_env_ok() {
let env = build_test_result_env().expect("build_test_result_env should succeed");
let missing = validate_result_env(&env);
assert!(missing.is_empty());
}
#[test]
fn test_validate_result_env_missing() {
let env = Environment::new();
let missing = validate_result_env(&env);
assert!(!missing.is_empty());
}
#[test]
fn test_mk_result_and_then() {
let r = mk_result_ok(Expr::BVar(0));
let f = Expr::Const(Name::str("f"), vec![]);
let e = mk_result_and_then(r, f);
assert!(matches!(e, Expr::App(_, _)));
}
#[test]
fn test_mk_result_map() {
let f = Expr::Const(Name::str("g"), vec![]);
let r = mk_result_ok(Expr::BVar(0));
let e = mk_result_map(f, r);
assert!(matches!(e, Expr::App(_, _)));
}
#[test]
fn test_mk_result_get_or_else() {
let default = Expr::Lit(oxilean_kernel::Literal::Nat(0));
let r = mk_result_err(Expr::Const(Name::str("err"), vec![]));
let e = mk_result_get_or_else(default, r);
assert!(matches!(e, Expr::App(_, _)));
}
#[test]
fn test_result_registry_all_names() {
let mut r = ResultRegistry::new();
r.register("Result");
r.register("Result.ok");
let names = r.all_names();
assert_eq!(names.len(), 2);
}
#[test]
fn test_build_test_result_env_ok() {
let env = build_test_result_env();
assert!(env.is_ok());
}
#[test]
fn test_error_accumulator_try_add_ok() {
let mut acc = ErrorAccumulator::new();
let v = acc.try_add(Ok::<String, String>("hello".to_string()));
assert_eq!(v, Some("hello".to_string()));
assert!(acc.is_empty());
}
#[test]
fn test_count_result_decls_full() {
let env = build_test_result_env().expect("build_test_result_env should succeed");
let c = count_result_decls(&env);
assert!(c >= 9);
}
}
pub fn res_ext_prop_axiom(name: &str, env: &mut Environment) -> std::result::Result<(), String> {
let prop = Expr::Sort(Level::zero());
env.add(Declaration::Axiom {
name: Name::str(name),
univ_params: vec![],
ty: prop,
})
.map_err(|e| e.to_string())
}
pub(super) fn res_ext_forall_type_axiom(
name: &str,
env: &mut Environment,
) -> std::result::Result<(), String> {
let prop = Expr::Sort(Level::zero());
let type1 = Expr::Sort(Level::succ(Level::zero()));
let ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1),
Box::new(prop),
);
env.add(Declaration::Axiom {
name: Name::str(name),
univ_params: vec![],
ty,
})
.map_err(|e| e.to_string())
}
pub(super) fn res_ext_forall2_axiom(
name: &str,
env: &mut Environment,
) -> std::result::Result<(), String> {
let prop = Expr::Sort(Level::zero());
let type1 = Expr::Sort(Level::succ(Level::zero()));
let ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1),
Box::new(prop),
)),
);
env.add(Declaration::Axiom {
name: Name::str(name),
univ_params: vec![],
ty,
})
.map_err(|e| e.to_string())
}
pub(super) fn res_ext_forall3_axiom(
name: &str,
env: &mut Environment,
) -> std::result::Result<(), String> {
let prop = Expr::Sort(Level::zero());
let type1 = Expr::Sort(Level::succ(Level::zero()));
let ty = Expr::Pi(
BinderInfo::Implicit,
Name::str("T"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("E"),
Box::new(type1.clone()),
Box::new(Expr::Pi(
BinderInfo::Implicit,
Name::str("U"),
Box::new(type1),
Box::new(prop),
)),
)),
);
env.add(Declaration::Axiom {
name: Name::str(name),
univ_params: vec![],
ty,
})
.map_err(|e| e.to_string())
}
pub fn res_ext_build_monad_left_identity(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.monad_left_identity", env)
}
pub fn res_ext_build_monad_right_identity(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.monad_right_identity", env)
}
pub fn res_ext_build_monad_assoc(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.monad_assoc", env)
}
pub fn res_ext_build_map_identity(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.map_identity", env)
}
pub fn res_ext_build_map_composition(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.map_composition", env)
}
pub fn res_ext_build_and_then_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.and_then_ok", env)
}
pub fn res_ext_build_and_then_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.and_then_err", env)
}
pub fn res_ext_build_or_else_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.or_else_ok", env)
}
pub fn res_ext_build_or_else_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.or_else_err", env)
}
pub fn res_ext_build_map_err_identity(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.map_err_identity", env)
}
pub fn res_ext_build_map_err_composition(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.map_err_composition", env)
}
pub fn res_ext_build_flatten_ok_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.flatten_ok_ok", env)
}
pub fn res_ext_build_flatten_ok_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.flatten_ok_err", env)
}
pub fn res_ext_build_flatten_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.flatten_err", env)
}
pub fn res_ext_build_bimap_identity(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.bimap_identity", env)
}
pub fn res_ext_build_bimap_composition(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.bimap_composition", env)
}
pub fn res_ext_build_bimap_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.bimap_ok", env)
}
pub fn res_ext_build_bimap_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.bimap_err", env)
}
pub fn res_ext_build_traverse_pure(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.traverse_pure", env)
}
pub fn res_ext_build_sequence_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.sequence_ok", env)
}
pub fn res_ext_build_sequence_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.sequence_err", env)
}
pub fn res_ext_build_dimap_identity(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.dimap_identity", env)
}
pub fn res_ext_build_dimap_composition(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.dimap_composition", env)
}
pub fn res_ext_build_ap_pure_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.ap_pure_ok", env)
}
pub fn res_ext_build_ap_err_left(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.ap_err_left", env)
}
pub fn res_ext_build_applicative_identity(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.applicative_identity", env)
}
pub fn res_ext_build_applicative_homomorphism(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.applicative_homomorphism", env)
}
pub fn res_ext_build_applicative_interchange(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.applicative_interchange", env)
}
pub fn res_ext_build_validation_ap_ok_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.validation_ap_ok_ok", env)
}
pub fn res_ext_build_validation_ap_err_accumulate(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.validation_ap_err_accumulate", env)
}
pub fn res_ext_build_fold_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.fold_ok", env)
}
pub fn res_ext_build_fold_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.fold_err", env)
}
pub fn res_ext_build_unfold_left(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.unfold_left", env)
}
pub fn res_ext_build_unfold_right(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.unfold_right", env)
}
pub fn res_ext_build_short_circuit_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.short_circuit_err", env)
}
pub fn res_ext_build_short_circuit_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.short_circuit_ok", env)
}
pub fn res_ext_build_result_t_lift_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("ResultT.lift_ok", env)
}
pub fn res_ext_build_result_t_lift_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("ResultT.lift_err", env)
}
pub fn res_ext_build_result_t_monad_left_id(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("ResultT.monad_left_identity", env)
}
pub fn res_ext_build_alt_ok_left(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.alt_ok_left", env)
}
pub fn res_ext_build_alt_err_left(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.alt_err_left", env)
}
pub fn res_ext_build_zip_ok_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.zip_ok_ok", env)
}
pub fn res_ext_build_zip_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.zip_err", env)
}
pub fn res_ext_build_zip_with_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.zipWith_ok", env)
}
pub fn res_ext_build_flatmap_fusion(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.flatmap_fusion", env)
}
pub fn res_ext_build_map_flatmap_fusion(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.map_flatmap_fusion", env)
}
pub fn res_ext_build_recover_with_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.recoverWith_ok", env)
}
pub fn res_ext_build_recover_with_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.recoverWith_err", env)
}
pub fn res_ext_build_tap_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.tap_ok", env)
}
pub fn res_ext_build_tap_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.tap_err", env)
}
pub fn res_ext_build_comonad_extract(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.comonad_extract", env)
}
pub fn res_ext_build_comonad_duplicate(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.comonad_duplicate", env)
}
pub fn res_ext_build_do_bind_desugar(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.do_notation_bind", env)
}
pub fn res_ext_build_do_return_desugar(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.do_notation_return", env)
}
pub fn res_ext_build_either_iso_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.either_iso_ok", env)
}
pub fn res_ext_build_either_iso_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.either_iso_err", env)
}
pub fn res_ext_build_either_roundtrip(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.either_roundtrip", env)
}
pub fn res_ext_build_join_left_id(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.join_left_id", env)
}
pub fn res_ext_build_join_assoc(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.join_assoc", env)
}
pub fn res_ext_build_lazy_eval_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.lazy_eval_ok", env)
}
pub fn res_ext_build_lazy_eval_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.lazy_eval_err", env)
}
pub fn res_ext_build_lazy_eval_idempotent(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.lazy_eval_idempotent", env)
}
pub fn res_ext_build_chain_ok_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.chain_ok_ok", env)
}
pub fn res_ext_build_chain_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.chain_err", env)
}
pub fn register_result_extended_axioms(env: &mut Environment) {
let builders: &[fn(&mut Environment) -> std::result::Result<(), String>] = &[
res_ext_build_monad_left_identity,
res_ext_build_monad_right_identity,
res_ext_build_monad_assoc,
res_ext_build_map_identity,
res_ext_build_map_composition,
res_ext_build_and_then_ok,
res_ext_build_and_then_err,
res_ext_build_or_else_ok,
res_ext_build_or_else_err,
res_ext_build_map_err_identity,
res_ext_build_map_err_composition,
res_ext_build_flatten_ok_ok,
res_ext_build_flatten_ok_err,
res_ext_build_flatten_err,
res_ext_build_bimap_identity,
res_ext_build_bimap_composition,
res_ext_build_bimap_ok,
res_ext_build_bimap_err,
res_ext_build_traverse_pure,
res_ext_build_sequence_ok,
res_ext_build_sequence_err,
res_ext_build_dimap_identity,
res_ext_build_dimap_composition,
res_ext_build_ap_pure_ok,
res_ext_build_ap_err_left,
res_ext_build_applicative_identity,
res_ext_build_applicative_homomorphism,
res_ext_build_applicative_interchange,
res_ext_build_validation_ap_ok_ok,
res_ext_build_validation_ap_err_accumulate,
res_ext_build_fold_ok,
res_ext_build_fold_err,
res_ext_build_unfold_left,
res_ext_build_unfold_right,
res_ext_build_short_circuit_err,
res_ext_build_short_circuit_ok,
res_ext_build_result_t_lift_ok,
res_ext_build_result_t_lift_err,
res_ext_build_result_t_monad_left_id,
res_ext_build_alt_ok_left,
res_ext_build_alt_err_left,
res_ext_build_zip_ok_ok,
res_ext_build_zip_err,
res_ext_build_zip_with_ok,
res_ext_build_flatmap_fusion,
res_ext_build_map_flatmap_fusion,
res_ext_build_recover_with_ok,
res_ext_build_recover_with_err,
res_ext_build_tap_ok,
res_ext_build_tap_err,
res_ext_build_comonad_extract,
res_ext_build_comonad_duplicate,
res_ext_build_do_bind_desugar,
res_ext_build_do_return_desugar,
res_ext_build_either_iso_ok,
res_ext_build_either_iso_err,
res_ext_build_either_roundtrip,
res_ext_build_join_left_id,
res_ext_build_join_assoc,
res_ext_build_lazy_eval_ok,
res_ext_build_lazy_eval_err,
res_ext_build_lazy_eval_idempotent,
res_ext_build_chain_ok_ok,
res_ext_build_chain_err,
];
for builder in builders {
let _ = builder(env);
}
}
#[cfg(test)]
mod result_extended_axiom_tests {
use super::*;
fn make_env() -> Environment {
let mut env = Environment::new();
let type1 = Expr::Sort(Level::succ(Level::zero()));
env.add(Declaration::Axiom {
name: Name::str("Bool"),
univ_params: vec![],
ty: type1,
})
.expect("operation should succeed");
build_result_env(&mut env).expect("build_result_env should succeed");
env
}
#[test]
fn test_register_result_extended_axioms_runs() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.monad_left_identity")).is_some());
assert!(env.get(&Name::str("Result.monad_right_identity")).is_some());
assert!(env.get(&Name::str("Result.monad_assoc")).is_some());
}
#[test]
fn test_monad_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.monad_left_identity")).is_some());
assert!(env.get(&Name::str("Result.monad_right_identity")).is_some());
assert!(env.get(&Name::str("Result.monad_assoc")).is_some());
}
#[test]
fn test_bifunctor_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.bimap_identity")).is_some());
assert!(env.get(&Name::str("Result.bimap_composition")).is_some());
assert!(env.get(&Name::str("Result.bimap_ok")).is_some());
assert!(env.get(&Name::str("Result.bimap_err")).is_some());
}
#[test]
fn test_applicative_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.applicative_identity")).is_some());
assert!(env
.get(&Name::str("Result.applicative_homomorphism"))
.is_some());
assert!(env
.get(&Name::str("Result.applicative_interchange"))
.is_some());
}
#[test]
fn test_traversal_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.traverse_pure")).is_some());
assert!(env.get(&Name::str("Result.sequence_ok")).is_some());
assert!(env.get(&Name::str("Result.sequence_err")).is_some());
}
#[test]
fn test_profunctor_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.dimap_identity")).is_some());
assert!(env.get(&Name::str("Result.dimap_composition")).is_some());
}
#[test]
fn test_validation_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.validation_ap_ok_ok")).is_some());
assert!(env
.get(&Name::str("Result.validation_ap_err_accumulate"))
.is_some());
}
#[test]
fn test_catamorphism_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.fold_ok")).is_some());
assert!(env.get(&Name::str("Result.fold_err")).is_some());
}
#[test]
fn test_anamorphism_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.unfold_left")).is_some());
assert!(env.get(&Name::str("Result.unfold_right")).is_some());
}
#[test]
fn test_short_circuit_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.short_circuit_err")).is_some());
assert!(env.get(&Name::str("Result.short_circuit_ok")).is_some());
}
#[test]
fn test_result_t_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("ResultT.lift_ok")).is_some());
assert!(env.get(&Name::str("ResultT.lift_err")).is_some());
assert!(env.get(&Name::str("ResultT.monad_left_identity")).is_some());
}
#[test]
fn test_alternative_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.alt_ok_left")).is_some());
assert!(env.get(&Name::str("Result.alt_err_left")).is_some());
}
#[test]
fn test_zip_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.zip_ok_ok")).is_some());
assert!(env.get(&Name::str("Result.zip_err")).is_some());
assert!(env.get(&Name::str("Result.zipWith_ok")).is_some());
}
#[test]
fn test_flatmap_fusion_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.flatmap_fusion")).is_some());
assert!(env.get(&Name::str("Result.map_flatmap_fusion")).is_some());
}
#[test]
fn test_recovery_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.recoverWith_ok")).is_some());
assert!(env.get(&Name::str("Result.recoverWith_err")).is_some());
assert!(env.get(&Name::str("Result.tap_ok")).is_some());
assert!(env.get(&Name::str("Result.tap_err")).is_some());
}
#[test]
fn test_comonad_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.comonad_extract")).is_some());
assert!(env.get(&Name::str("Result.comonad_duplicate")).is_some());
}
#[test]
fn test_do_notation_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.do_notation_bind")).is_some());
assert!(env.get(&Name::str("Result.do_notation_return")).is_some());
}
#[test]
fn test_either_iso_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.either_iso_ok")).is_some());
assert!(env.get(&Name::str("Result.either_iso_err")).is_some());
assert!(env.get(&Name::str("Result.either_roundtrip")).is_some());
}
#[test]
fn test_join_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.join_left_id")).is_some());
assert!(env.get(&Name::str("Result.join_assoc")).is_some());
}
#[test]
fn test_lazy_eval_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.lazy_eval_ok")).is_some());
assert!(env.get(&Name::str("Result.lazy_eval_err")).is_some());
assert!(env.get(&Name::str("Result.lazy_eval_idempotent")).is_some());
}
#[test]
fn test_chain_laws_present() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
assert!(env.get(&Name::str("Result.chain_ok_ok")).is_some());
assert!(env.get(&Name::str("Result.chain_err")).is_some());
}
#[test]
fn test_result_axiom_registry_ops() {
let mut reg = ResultAxiomRegistry::new();
reg.register("Result.monad_left_identity");
reg.register("Result.monad_right_identity");
assert_eq!(reg.len(), 2);
assert!(!reg.is_empty());
}
#[test]
fn test_validation_collector_all_ok() {
let mut col: ValidationCollector<i32, String> = ValidationCollector::with_capacity(4);
col.push(Ok(1));
col.push(Ok(2));
col.push(Ok(3));
assert!(col.is_valid());
let result = col.finish();
assert_eq!(result.expect("result should be valid"), vec![1, 2, 3]);
}
#[test]
fn test_validation_collector_with_errors() {
let mut col: ValidationCollector<i32, String> = ValidationCollector::with_capacity(4);
col.push(Ok(1));
col.push(Err("bad".to_string()));
col.push(Ok(2));
col.push(Err("worse".to_string()));
assert!(!col.is_valid());
let result = col.finish();
let errs = result.unwrap_err();
assert_eq!(errs.len(), 2);
}
#[test]
fn test_result_either_bridge() {
let std_bridge = ResultEitherBridge::standard();
assert!(!std_bridge.flip_convention);
let flip_bridge = ResultEitherBridge::flipped();
assert!(flip_bridge.flip_convention);
}
#[test]
fn test_prop_axiom_is_sort_zero() {
let mut env = Environment::new();
res_ext_prop_axiom("test.prop", &mut env).expect("Environment::new should succeed");
let decl = env
.get(&Name::str("test.prop"))
.expect("declaration 'test.prop' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
#[test]
fn test_extended_axioms_are_axiom_kind() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
let decl = env
.get(&Name::str("Result.monad_left_identity"))
.expect("declaration 'Result.monad_left_identity' should exist in env");
assert!(matches!(decl, Declaration::Axiom { .. }));
}
#[test]
fn test_all_35_plus_axioms_registered() {
let mut env = make_env();
register_result_extended_axioms(&mut env);
let axiom_names = [
"Result.monad_left_identity",
"Result.monad_right_identity",
"Result.monad_assoc",
"Result.map_identity",
"Result.map_composition",
"Result.and_then_ok",
"Result.and_then_err",
"Result.or_else_ok",
"Result.or_else_err",
"Result.map_err_identity",
"Result.map_err_composition",
"Result.flatten_ok_ok",
"Result.flatten_ok_err",
"Result.flatten_err",
"Result.bimap_identity",
"Result.bimap_composition",
"Result.bimap_ok",
"Result.bimap_err",
"Result.traverse_pure",
"Result.sequence_ok",
"Result.sequence_err",
"Result.dimap_identity",
"Result.dimap_composition",
"Result.ap_pure_ok",
"Result.ap_err_left",
"Result.applicative_identity",
"Result.applicative_homomorphism",
"Result.applicative_interchange",
"Result.validation_ap_ok_ok",
"Result.validation_ap_err_accumulate",
"Result.fold_ok",
"Result.fold_err",
"Result.unfold_left",
"Result.unfold_right",
"Result.short_circuit_err",
"Result.short_circuit_ok",
];
let mut found = 0usize;
for name in &axiom_names {
if env.get(&Name::str(*name)).is_some() {
found += 1;
}
}
assert!(found >= 35, "Expected at least 35 axioms, found {}", found);
}
}
pub(super) fn res_ext2_build_strength_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.strength_ok", env)
}
pub(super) fn res_ext2_build_strength_err(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.strength_err", env)
}
pub(super) fn res_ext2_build_natural_transform_ok(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.natural_transform_ok", env)
}
pub(super) fn res_ext2_build_natural_transform_err(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.natural_transform_err", env)
}
pub(super) fn res_ext2_build_monad_morphism_unit(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.monad_morphism_unit", env)
}
pub(super) fn res_ext2_build_monad_morphism_bind(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.monad_morphism_bind", env)
}
pub(super) fn res_ext2_build_distribute_list_result(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.distribute_list_result", env)
}
pub(super) fn res_ext2_build_pointed_pure(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.pointed_pure", env)
}
pub(super) fn res_ext2_build_lens_get_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.lens_get_ok", env)
}
pub(super) fn res_ext2_build_lens_set_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall3_axiom("Result.lens_set_ok", env)
}
pub(super) fn res_ext2_build_prism_review(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.prism_review", env)
}
pub(super) fn res_ext2_build_prism_preview_ok(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.prism_preview_ok", env)
}
pub(super) fn res_ext2_build_prism_preview_err(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.prism_preview_err", env)
}
pub(super) fn res_ext2_build_swap_ok(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.swap_ok", env)
}
pub(super) fn res_ext2_build_swap_err(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.swap_err", env)
}
pub(super) fn res_ext2_build_swap_involution(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.swap_involution", env)
}
pub(super) fn res_ext2_build_unwrap_or_default_ok(
env: &mut Environment,
) -> std::result::Result<(), String> {
res_ext_forall_type_axiom("Result.unwrap_or_default_ok", env)
}
pub(super) fn res_ext2_build_ok_or_else(env: &mut Environment) -> std::result::Result<(), String> {
res_ext_forall2_axiom("Result.ok_or_else", env)
}