use geoit::algebra::mv::Mv;
use geoit::algebra::signature::Signature;
use geoit::governance::field::FieldOp;
use geoit::governance::geom_class::{inner_product_poly, norm_poly};
use geoit::governance::poly::Poly;
use geoit::governance::{govern, Construction, Expr, GeomClass, Governance, Phase, VariableMap};
use geoit::scalar::{Rat, Scalar};
fn assert_circuit(gov: &Governance, params: &[Scalar], expected_phase: Phase, label: &str) {
let mv = gov
.construct(0, params)
.unwrap_or_else(|e| panic!("{}: construct: {}", label, e));
let geoit = govern(&mv, gov, 0).unwrap_or_else(|e| panic!("{}: govern: {}", label, e));
assert!(geoit.is_satisfied(), "{}: predicate failed", label);
assert_eq!(geoit.phase(), expected_phase, "{}: wrong phase", label);
assert_eq!(
geoit.read_all().unwrap(),
params,
"{}: circuit failed",
label
);
}
fn vga_vector_body(arity: usize, gen_offset: u8) -> Expr {
let mut terms: Vec<Expr> = (0..arity)
.map(|i| {
Expr::Mul(
Expr::param(i),
Box::new(Expr::Generator(gen_offset + i as u8)),
)
})
.collect();
let mut r = terms.remove(0);
for t in terms {
r = Expr::Add(Box::new(r), Box::new(t));
}
r
}
#[test]
fn algebra_01_vga2() {
let gov = Governance {
sig: Signature::new(0, 0, 2).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 2,
body: vga_vector_body(2, 0),
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[Scalar::from(3i64), Scalar::from(4i64)],
Phase::Commitment,
"VGA2",
);
}
#[test]
fn algebra_02_vga3() {
let gov = Governance {
sig: Signature::new(0, 0, 3).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 3,
body: vga_vector_body(3, 0),
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)],
Phase::Commitment,
"VGA3",
);
assert_circuit(
&gov,
&[
Scalar::Rat(Rat::new(1, 2)),
Scalar::Rat(Rat::new(1, 3)),
Scalar::Rat(Rat::new(1, 7)),
],
Phase::Commitment,
"VGA3-rat",
);
}
#[test]
fn algebra_03_pga2() {
let sig = Signature::new(0, 1, 2).unwrap();
let gm = 0b100u64; let vm = VariableMap::for_grade_mask(&sig, gm);
let weight_poly = Poly::variable(*vm.mask_to_var.get(&0b110).unwrap(), vm.num_vars);
let e02 = Expr::mul(Expr::gen(0), Expr::gen(2));
let e01 = Expr::mul(Expr::gen(0), Expr::gen(1));
let e12 = Expr::mul(Expr::gen(1), Expr::gen(2));
let body = Expr::Add(
Expr::add(
Expr::mul(Expr::param(0), e02),
Expr::neg(Expr::mul(Expr::param(1), e01)),
),
e12,
);
let gov = Governance {
sig,
derived_gens: vec![],
geom_classes: vec![GeomClass {
grade_mask: gm,
equations: vec![],
inequalities: vec![weight_poly],
field_op: FieldOp::default(),
expected_profile: None,
}],
constructions: vec![Construction {
class_index: 0,
arity: 2,
body,
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[Scalar::from(3i64), Scalar::from(4i64)],
Phase::Evaluation,
"PGA2",
);
assert_circuit(
&gov,
&[Scalar::from(0i64), Scalar::from(0i64)],
Phase::Commitment,
"PGA2(0,0)",
);
}
#[test]
fn algebra_04_pga3() {
let sig = Signature::new(0, 1, 3).unwrap();
let gm = 0b1000u64; let vm = VariableMap::for_grade_mask(&sig, gm);
let weight_poly = Poly::variable(*vm.mask_to_var.get(&0b1110).unwrap(), vm.num_vars);
let e023 = Expr::mul(Expr::mul(Expr::gen(0), Expr::gen(2)), Expr::gen(3));
let e013 = Expr::mul(Expr::mul(Expr::gen(0), Expr::gen(1)), Expr::gen(3));
let e012 = Expr::mul(Expr::mul(Expr::gen(0), Expr::gen(1)), Expr::gen(2));
let e123 = Expr::mul(Expr::mul(Expr::gen(1), Expr::gen(2)), Expr::gen(3));
let body = Expr::Add(
Expr::add(
Expr::add(
Expr::mul(Expr::param(0), e023),
Expr::neg(Expr::mul(Expr::param(1), e013)),
),
Expr::mul(Expr::param(2), e012),
),
e123,
);
let gov = Governance {
sig,
derived_gens: vec![],
geom_classes: vec![GeomClass {
grade_mask: gm,
equations: vec![],
inequalities: vec![weight_poly],
field_op: FieldOp::default(),
expected_profile: None,
}],
constructions: vec![Construction {
class_index: 0,
arity: 3,
body,
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[Scalar::from(1i64), Scalar::from(2i64), Scalar::from(3i64)],
Phase::Evaluation,
"PGA3",
);
}
fn cga_gov(i: u8, h: u8, euclidean_gens: &[u8]) -> Governance {
let sig = Signature::new(i, 0, h).unwrap();
let gm = 0b10u64; let e_origin = Mv::from_rat_terms(&[(0b00001, Rat::new(1, 2)), (0b00010, Rat::new(1, 2))]);
let e_infinity = Mv::from_rat_terms(&[(0b00001, Rat::from(-1)), (0b00010, Rat::from(1))]);
let vm = VariableMap::for_grade_mask(&sig, gm);
let null_eq = norm_poly(&sig, gm, vm.num_vars, &vm.mask_to_var);
let ip_eq = inner_product_poly(
&e_infinity,
&sig,
gm,
Rat::ONE,
vm.num_vars,
&vm.mask_to_var,
);
let class = GeomClass {
grade_mask: gm,
equations: vec![null_eq, ip_eq],
inequalities: vec![],
field_op: FieldOp::default(),
expected_profile: None,
};
let n_eucl = euclidean_gens.len();
let mut euc_terms: Vec<Expr> = euclidean_gens
.iter()
.enumerate()
.map(|(pi, &gi)| Expr::Mul(Expr::param(pi), Box::new(Expr::Generator(gi))))
.collect();
let mut euclidean = euc_terms.remove(0);
for t in euc_terms {
euclidean = Expr::Add(Box::new(euclidean), Box::new(t));
}
let mut r2_terms: Vec<Expr> = (0..n_eucl)
.map(|pi| Expr::Mul(Expr::param(pi), Expr::param(pi)))
.collect();
let mut r_squared = r2_terms.remove(0);
for t in r2_terms {
r_squared = Expr::Add(Box::new(r_squared), Box::new(t));
}
let neg_half_r2 = Expr::mul(
Box::new(Expr::Literal(Scalar::Rat(Rat::new(-1, 2)))),
Box::new(r_squared),
);
let conformal = Expr::Mul(neg_half_r2, Expr::dgen(1));
let body = Expr::Add(
Box::new(Expr::Add(Box::new(euclidean), Box::new(conformal))),
Expr::dgen(0),
);
Governance {
sig,
derived_gens: vec![e_origin, e_infinity],
geom_classes: vec![class],
constructions: vec![Construction {
class_index: 0,
arity: n_eucl,
body,
}],
probe: None,
transform_rules: vec![],
}
}
#[test]
fn algebra_05_cga2() {
let gov = cga_gov(1, 3, &[2, 3]);
assert_circuit(
&gov,
&[Scalar::from(0i64), Scalar::from(0i64)],
Phase::Evaluation,
"CGA2 origin",
);
assert_circuit(
&gov,
&[Scalar::from(3i64), Scalar::from(4i64)],
Phase::Evaluation,
"CGA2(3,4)",
);
}
#[test]
fn algebra_06_cga3() {
let gov = cga_gov(1, 4, &[2, 3, 4]);
assert_circuit(
&gov,
&[Scalar::from(0i64), Scalar::from(0i64), Scalar::from(0i64)],
Phase::Evaluation,
"CGA3 origin",
);
assert_circuit(
&gov,
&[Scalar::from(3i64), Scalar::from(4i64), Scalar::from(5i64)],
Phase::Evaluation,
"CGA3(3,4,5)",
);
assert_circuit(
&gov,
&[
Scalar::Rat(Rat::new(1, 2)),
Scalar::Rat(Rat::new(1, 3)),
Scalar::Rat(Rat::new(1, 7)),
],
Phase::Evaluation,
"CGA3 rat",
);
}
#[test]
fn algebra_07_sta_wc() {
let body = Expr::Add(
Expr::add(
Expr::add(
Expr::mul(Expr::param(0), Expr::gen(3)),
Expr::mul(Expr::param(1), Expr::gen(0)),
),
Expr::mul(Expr::param(2), Expr::gen(1)),
),
Expr::mul(Expr::param(3), Expr::gen(2)),
);
let gov = Governance {
sig: Signature::new(3, 0, 1).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 4,
body,
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[
Scalar::from(5i64),
Scalar::from(1i64),
Scalar::from(0i64),
Scalar::from(0i64),
],
Phase::Commitment,
"STA-WC timelike",
);
assert_circuit(
&gov,
&[
Scalar::from(0i64),
Scalar::from(3i64),
Scalar::from(4i64),
Scalar::from(0i64),
],
Phase::Deliberation,
"STA-WC spacelike",
);
assert_circuit(
&gov,
&[
Scalar::from(5i64),
Scalar::from(3i64),
Scalar::from(4i64),
Scalar::from(0i64),
],
Phase::Evaluation,
"STA-WC null",
);
}
#[test]
fn algebra_08_sta_ec() {
let body = Expr::Add(
Expr::add(
Expr::add(
Expr::mul(Expr::param(0), Expr::gen(0)),
Expr::mul(Expr::param(1), Expr::gen(1)),
),
Expr::mul(Expr::param(2), Expr::gen(2)),
),
Expr::mul(Expr::param(3), Expr::gen(3)),
);
let gov = Governance {
sig: Signature::new(1, 0, 3).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 4,
body,
}],
probe: None,
transform_rules: vec![],
};
assert_circuit(
&gov,
&[
Scalar::from(5i64),
Scalar::from(1i64),
Scalar::from(0i64),
Scalar::from(0i64),
],
Phase::Deliberation,
"STA-EC timelike",
);
assert_circuit(
&gov,
&[
Scalar::from(0i64),
Scalar::from(3i64),
Scalar::from(4i64),
Scalar::from(0i64),
],
Phase::Commitment,
"STA-EC spacelike",
);
assert_circuit(
&gov,
&[
Scalar::from(5i64),
Scalar::from(3i64),
Scalar::from(4i64),
Scalar::from(0i64),
],
Phase::Evaluation,
"STA-EC null",
);
}
#[test]
fn sta_convention_is_data() {
let wc_body = Expr::Add(
Expr::add(
Expr::add(
Expr::mul(Expr::param(0), Expr::gen(3)),
Expr::mul(Expr::param(1), Expr::gen(0)),
),
Expr::mul(Expr::param(2), Expr::gen(1)),
),
Expr::mul(Expr::param(3), Expr::gen(2)),
);
let ec_body = Expr::Add(
Expr::add(
Expr::add(
Expr::mul(Expr::param(0), Expr::gen(0)),
Expr::mul(Expr::param(1), Expr::gen(1)),
),
Expr::mul(Expr::param(2), Expr::gen(2)),
),
Expr::mul(Expr::param(3), Expr::gen(3)),
);
let wc = Governance {
sig: Signature::new(3, 0, 1).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 4,
body: wc_body,
}],
probe: None,
transform_rules: vec![],
};
let ec = Governance {
sig: Signature::new(1, 0, 3).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 4,
body: ec_body,
}],
probe: None,
transform_rules: vec![],
};
let p = vec![
Scalar::from(5i64),
Scalar::from(3i64),
Scalar::from(4i64),
Scalar::from(0i64),
];
let mv_wc = wc.construct(0, &p).unwrap();
let mv_ec = ec.construct(0, &p).unwrap();
assert_eq!(govern(&mv_wc, &wc, 0).unwrap().phase(), Phase::Evaluation);
assert_eq!(govern(&mv_ec, &ec, 0).unwrap().phase(), Phase::Evaluation);
assert_ne!(mv_wc, mv_ec);
}
#[test]
fn algebra_09_qga3() {
let gov = Governance {
sig: Signature::new(3, 0, 6).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 9,
body: vga_vector_body(9, 0),
}],
probe: None,
transform_rules: vec![],
};
let params: Vec<Scalar> = (1..=9).map(|i| Scalar::from(i as i64)).collect();
assert_circuit(&gov, ¶ms, Phase::Commitment, "QGA3");
}
#[test]
fn algebra_10_qcga() {
let gov = Governance {
sig: Signature::new(6, 0, 9).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 15,
body: vga_vector_body(15, 0),
}],
probe: None,
transform_rules: vec![],
};
let params: Vec<Scalar> = vec![Scalar::from(1i64); 15];
assert_circuit(&gov, ¶ms, Phase::Commitment, "QCGA");
}
#[test]
fn all_algebras_summary() {
let algebras: Vec<(&str, Governance, usize)> = vec![
(
"VGA2",
Governance {
sig: Signature::new(0, 0, 2).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 2,
body: vga_vector_body(2, 0),
}],
probe: None,
transform_rules: vec![],
},
2,
),
(
"VGA3",
Governance {
sig: Signature::new(0, 0, 3).unwrap(),
derived_gens: vec![],
geom_classes: vec![GeomClass::grades_only(&[1])],
constructions: vec![Construction {
class_index: 0,
arity: 3,
body: vga_vector_body(3, 0),
}],
probe: None,
transform_rules: vec![],
},
3,
),
];
for (name, gov, arity) in &algebras {
let mut params = vec![Scalar::from(0i64); *arity];
let first_h = (gov.sig.i() + gov.sig.d()) as usize;
if first_h < *arity {
params[first_h] = Scalar::from(1i64);
} else {
params[0] = Scalar::from(1i64);
}
let mv = gov.construct(0, ¶ms).unwrap();
let geoit = govern(&mv, &gov, 0).unwrap();
assert_eq!(geoit.read_all().unwrap(), params, "{} failed", name);
}
}