/* TODO FIXME si prelude regressions use lsts::tlc::TLC; #[test] fn check_constant_literals() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //soft cast literals into typed values tlc.check(Some(si), "True:Boolean;").unwrap(); tlc.check(Some(si), "False:Boolean;").unwrap(); tlc.check(Some(si), "1:Boolean;").unwrap_err(); tlc.check(Some(si), "0:Integer;").unwrap(); tlc.check(Some(si), "321:Integer;").unwrap(); tlc.check(Some(si), "3e2:Integer;").unwrap(); tlc.check(Some(si), "3.2:Integer;").unwrap_err(); tlc.check(Some(si), "3+1i:Integer;").unwrap_err(); tlc.check(Some(si), "True:Integer;").unwrap_err(); tlc.check(Some(si), "0:Real;").unwrap(); tlc.check(Some(si), "321:Real;").unwrap(); tlc.check(Some(si), "3e2:Real;").unwrap(); tlc.check(Some(si), "3.2:Real;").unwrap(); tlc.check(Some(si), "3+1i:Real;").unwrap_err(); tlc.check(Some(si), "3.2+1i:Real;").unwrap_err(); tlc.check(Some(si), "True:Real;").unwrap_err(); tlc.check(Some(si), "0:Complex;").unwrap(); tlc.check(Some(si), "321:Complex;").unwrap(); tlc.check(Some(si), "3e2:Complex;").unwrap(); tlc.check(Some(si), "3.2:Complex;").unwrap(); tlc.check(Some(si), "3+1i:Complex;").unwrap(); tlc.check(Some(si), "3.2+1i:Complex;").unwrap(); tlc.check(Some(si), "True:Complex;").unwrap_err(); } #[test] fn check_type_equality() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //Ground Types unify with themselves tlc.check(Some(si), "let x:Integer=1:Integer;").unwrap(); tlc.check(Some(si), "let x:Real=1:Real;").unwrap(); tlc.check(Some(si), "let x:Complex=1:Complex;").unwrap(); //Ground Types unify with other Types when a viable cast rule is available //tlc.check(Some(si), "let x:Real=1:Integer;").unwrap(); //tlc.check(Some(si), "let x:Complex=1:Integer;").unwrap(); //tlc.check(Some(si), "let x:Complex=1:Real;").unwrap(); //Ground Types do not unify if no cast rule is available tlc.check(Some(si), "let x:Integer=1:Real;").unwrap_err(); tlc.check(Some(si), "let x:Integer=1:Complex;").unwrap_err(); tlc.check(Some(si), "let x:Real=1:Complex;").unwrap_err(); } #[test] fn check_tik_i() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); tlc.check(Some(si), "let xy: Point2D;").unwrap(); tlc.check(Some(si), "let xy: Point2D;").unwrap_err(); } #[test] fn check_compound_types() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //use constructors tlc.check(Some(si), "Point2D { x=1:Integer, y=2:Integer };").unwrap(); //tlc.check(Some(si), "Point2D { x=True:Boolean, y=1:Integer };").unwrap_err(); //tlc.check(Some(si), "Point2D { x=True:Boolean, y=False:Boolean };").unwrap_err(); tlc.check(Some(si), "Point3D { x=1:Integer, y=2:Integer, z=1:Integer };").unwrap(); //tlc.check(Some(si), "Point3D { x=1:Integer, y=2:Integer, z=False:Boolean };").unwrap_err(); //tlc.check(Some(si), "Point3D { x=True:Boolean, y=False:Boolean, z=False:Boolean };").unwrap_err(); //use fields tlc.check(Some(si), "let xy: Point2D; xy.x:Integer;").unwrap(); tlc.check(Some(si), "let xy: Point2D; xy.y:Integer;").unwrap(); tlc.check(Some(si), "let xy: Point2D; xy.z:Integer;").unwrap_err(); tlc.check(Some(si), "let xy: Point2D; xy.x:Real;").unwrap(); tlc.check(Some(si), "let xy: Point2D; xy.y:Real;").unwrap(); tlc.check(Some(si), "let xy: Point2D; xy.z:Real;").unwrap_err(); tlc.check(Some(si), "let xy: Point2D; xy.x:Integer;").unwrap_err(); tlc.check(Some(si), "let xy: Point2D; xy.y:Integer;").unwrap_err(); tlc.check(Some(si), "let xy: Point2D; xy.z:Integer;").unwrap_err(); tlc.check(Some(si), "let xyz: Point3D; xyz.x:Integer;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.y:Integer;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.z:Integer;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.x:Real;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.y:Real;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.z:Real;").unwrap(); tlc.check(Some(si), "let xyz: Point3D; xyz.x:Integer;").unwrap_err(); tlc.check(Some(si), "let xyz: Point3D; xyz.y:Integer;").unwrap_err(); tlc.check(Some(si), "let xyz: Point3D; xyz.z:Integer;").unwrap_err(); } #[test] fn check_type_cast() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible numerical types tlc.check(Some(si), "True as Boolean;").unwrap(); tlc.check(Some(si), "True as Integer;").unwrap_err(); tlc.check(Some(si), "1:Integer as Integer;").unwrap(); tlc.check(Some(si), "1:Integer as Real;").unwrap(); tlc.check(Some(si), "1:Integer as Complex;").unwrap(); tlc.check(Some(si), "1:Real as Integer;").unwrap_err(); tlc.check(Some(si), "1:Real as Real;").unwrap(); tlc.check(Some(si), "1:Real as Complex;").unwrap(); tlc.check(Some(si), "1:Complex as Integer;").unwrap_err(); tlc.check(Some(si), "1:Complex as Real;").unwrap_err(); tlc.check(Some(si), "1:Complex as Complex;").unwrap(); } #[test] fn check_project_kinded() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //It is ok to let the compiler infer the Term type tlc.check(Some(si), "True;").unwrap(); //should be a Boolean tlc.check(Some(si), "1;").unwrap(); //should be an Integer number tlc.check(Some(si), "1.2;").unwrap(); //should be a Real number tlc.check(Some(si), "1.2+3i;").unwrap(); //should be an Complex number } #[test] fn check_unit_math() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check math operations tlc.check(Some(si), "let x: Metre; +x:Metre;").unwrap(); tlc.check(Some(si), "let x: Metre; +x:Second;").unwrap_err(); tlc.check(Some(si), "let x: Metre; -x:Metre;").unwrap(); tlc.check(Some(si), "let x: Metre; -x:Second;").unwrap_err(); tlc.check(Some(si), "let x: Metre; let y: Metre; x+y:Metre;").unwrap(); tlc.check(Some(si), "let x: Metre; let y: Second; x+y:Metre;").unwrap_err(); tlc.check(Some(si), "let x: Metre; let y: Metre; x-y:Metre;").unwrap(); tlc.check(Some(si), "let x: Metre; let y: Second; x-y:Metre;").unwrap_err(); tlc.check(Some(si), "let x: Metre; let y: Second; x*y:Metre*Second;").unwrap(); tlc.check(Some(si), "let x: Metre; let y: Metre; x*y:Metre*Second;").unwrap_err(); tlc.check(Some(si), "let x: Metre; let y: Second; x/y:Metre/Second;").unwrap(); tlc.check(Some(si), "let x: Metre; let y: Metre; x/y:Metre/Second;").unwrap_err(); } #[test] fn check_narrow_type_cast() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible types within a kind tlc.check(Some(si), "(1:Integer+Metre) as Integer;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre) as Real;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre) as Complex;").unwrap(); tlc.check(Some(si), "(1:Real+Metre) as Integer;").unwrap_err(); tlc.check(Some(si), "(1:Real+Metre) as Real;").unwrap(); tlc.check(Some(si), "(1:Real+Metre) as Complex;").unwrap(); tlc.check(Some(si), "(1:Complex+Metre) as Integer;").unwrap_err(); tlc.check(Some(si), "(1:Complex+Metre) as Real;").unwrap_err(); tlc.check(Some(si), "(1:Complex+Metre) as Complex;").unwrap(); } #[test] fn check_narrow_noop_conversion() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible types within a kind tlc.check(Some(si), "(1:Integer+Speed) as Metre/Second;").unwrap(); tlc.check(Some(si), "(1:Integer+Speed) as Metre;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Speed) as Second;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Metre/Second) as Speed;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre) as Speed;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Second) as Speed;").unwrap_err(); } #[test] fn check_narrow_conversion() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible types within a kind tlc.check(Some(si), "(1:Integer+Minute) as Hour;").unwrap(); tlc.check(Some(si), "(1:Integer+Minute) as Metre;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Kilo) as Metre;").unwrap(); tlc.check(Some(si), "(1:Integer+Kilo) as Second;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Metre) as Kilo;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre) as Kilo;").unwrap_err(); } #[test] fn check_unit_conversion() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check unit conversions tlc.check(Some(si), "let x: Kilo; x as Metre;").unwrap(); tlc.check(Some(si), "let x: Kilo; x as Second;").unwrap_err(); tlc.check(Some(si), "let x: Metre; x as Kilo;").unwrap(); tlc.check(Some(si), "let x: Metre; x as Kilo;").unwrap_err(); } #[test] fn check_ratio_conversion() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible types within a kind tlc.check(Some(si), "(1:Integer+Kilo/Second) as Metre/Second;").unwrap(); tlc.check(Some(si), "(1:Integer+Kilo/Second) as Second/Second;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Metre/Second) as Kilo/Second;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre/Second) as Kilo/Second;").unwrap_err(); } #[test] fn check_imperial_conversion() { let mut tlc = TLC::new(); let si = tlc.import_file(None, "preludes/si.tlc").unwrap(); //check type cast of compatible types within a kind tlc.check(Some(si), "(1:Integer+Kilo/Second) as Mile/Minute;").unwrap(); tlc.check(Some(si), "(1:Integer+Kilo/Second) as Watt/Minute;").unwrap_err(); tlc.check(Some(si), "(1:Integer+Metre/Second) as Mile/Minute;").unwrap(); tlc.check(Some(si), "(1:Integer+Metre/Second) as Watt/Minute;").unwrap_err(); } */