diff --git a/Cargo.lock b/Cargo.lock index 89865ccf..8197a341 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -202,6 +202,7 @@ dependencies = [ "dyntest", "hvm64-ast", "hvm64-host", + "hvm64-num", "hvm64-runtime", "hvm64-transform", "hvm64-util", @@ -214,8 +215,8 @@ name = "hvm64-ast" version = "0.3.0" dependencies = [ "TSPL", + "hvm64-num", "hvm64-util", - "ordered-float", ] [[package]] @@ -223,14 +224,23 @@ name = "hvm64-host" version = "0.3.0" dependencies = [ "hvm64-ast", + "hvm64-num", "hvm64-runtime", "hvm64-util", ] +[[package]] +name = "hvm64-num" +version = "0.3.0" +dependencies = [ + "hvm64-util", +] + [[package]] name = "hvm64-runtime" version = "0.3.0" dependencies = [ + "hvm64-num", "hvm64-util", ] @@ -240,6 +250,7 @@ version = "0.3.0" dependencies = [ "hvm64-ast", "hvm64-host", + "hvm64-num", "hvm64-runtime", "hvm64-util", "ordered-float", diff --git a/Cargo.toml b/Cargo.toml index 5130e35f..006dfd44 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -30,6 +30,7 @@ hvm64-runtime = { path = "./runtime" } hvm64-transform = { path = "./transform" } hvm64-util = { path = "./util" } hvm64-host = { path = "./host" } +hvm64-num = { path = "./num" } [dev-dependencies] insta = { version = "1.34.0", features = ["glob"] } diff --git a/ast/Cargo.toml b/ast/Cargo.toml index 0ccca293..c395f35e 100644 --- a/ast/Cargo.toml +++ b/ast/Cargo.toml @@ -7,14 +7,14 @@ edition = "2021" path = "src/ast.rs" [dependencies] -ordered-float = { version = "4.2.0", default-features = false } TSPL = { git = "https://github.com/tjjfvi/TSPL", branch = "no_std", optional = true } hvm64-util = { path = "../util", default-features = false } +hvm64-num = { path = "../num", default-features = false } [features] default = ["std", "parser"] -std = ["hvm64-util/std"] +std = ["hvm64-util/std", "hvm64-num/std"] parser = ["dep:TSPL"] [lints] diff --git a/ast/src/ast.rs b/ast/src/ast.rs index 11d5479c..7b1ed35f 100644 --- a/ast/src/ast.rs +++ b/ast/src/ast.rs @@ -16,9 +16,8 @@ mod parser; use alloc::collections::BTreeMap; -use hvm64_util::{create_var, deref_to, maybe_grow, multi_iterator, ops::TypedOp as Op, prelude::*, var_to_num}; - -use ordered_float::OrderedFloat; +use hvm64_num::Num; +use hvm64_util::{create_var, deref_to, maybe_grow, multi_iterator, prelude::*, var_to_num}; pub type Lab = u16; @@ -59,26 +58,22 @@ pub enum Tree { #[default] /// A nilary eraser node. Era, - /// A native 60-bit integer. - Int { val: i64 }, - /// A native 32-bit float. - F32 { val: OrderedFloat }, + /// A native number. + Num(Num), /// A nilary node, referencing a named net. - Ref { nam: String }, + Ref(String), /// A n-ary interaction combinator. Ctr { /// The label of the combinator. (Combinators with the same label /// annihilate, and combinators with different labels commute.) lab: Lab, - lft: Box, - rgt: Box, + p1: Box, + p2: Box, }, /// A binary node representing an operation on native integers. /// /// The principal port connects to the left operand. Op { - /// The operation associated with this node. - op: Op, /// An auxiliary port; connects to the right operand. rhs: Box, /// An auxiliary port; connects to the output. @@ -87,7 +82,7 @@ pub enum Tree { /// A binary node representing a match on native integers. /// /// The principal port connects to the integer to be matched on. - Mat { + Switch { /// An auxiliary port; connects to a tree of the following structure: /// ```text /// (+value_if_zero (-predecessor_of_number +value_if_succ)) @@ -97,7 +92,7 @@ pub enum Tree { out: Box, }, /// One side of a wire; the other side will have the same name. - Var { nam: String }, + Var(String), } impl Net { @@ -122,8 +117,8 @@ impl Net { let fresh_str = create_var(fresh + 1); let fun = mem::take(&mut self.root); - let app = Tree::Ctr { lab: 0, lft: Box::new(arg), rgt: Box::new(Tree::Var { nam: fresh_str.clone() }) }; - self.root = Tree::Var { nam: fresh_str }; + let app = Tree::Ctr { lab: 0, p1: Box::new(arg), p2: Box::new(Tree::Var(fresh_str.clone())) }; + self.root = Tree::Var(fresh_str); self.redexes.push((fun, app)); } @@ -141,10 +136,10 @@ impl Tree { pub fn children(&self) -> impl ExactSizeIterator + DoubleEndedIterator { multi_iterator! { Iter { Nil, Two } } match self { - Tree::Era | Tree::Int { .. } | Tree::F32 { .. } | Tree::Ref { .. } | Tree::Var { .. } => Iter::Nil([]), - Tree::Ctr { lft, rgt, .. } => Iter::Two([&**lft, rgt]), + Tree::Era | Tree::Num(..) | Tree::Ref(_) | Tree::Var(_) => Iter::Nil([]), + Tree::Ctr { p1, p2, .. } => Iter::Two([&**p1, p2]), Tree::Op { rhs, out, .. } => Iter::Two([&**rhs, out]), - Tree::Mat { arms, out } => Iter::Two([&**arms, out]), + Tree::Switch { arms, out } => Iter::Two([&**arms, out]), } } @@ -152,10 +147,10 @@ impl Tree { pub fn children_mut(&mut self) -> impl ExactSizeIterator + DoubleEndedIterator { multi_iterator! { Iter { Nil, Two } } match self { - Tree::Era | Tree::Int { .. } | Tree::F32 { .. } | Tree::Ref { .. } | Tree::Var { .. } => Iter::Nil([]), - Tree::Ctr { lft, rgt, .. } => Iter::Two([&mut **lft, rgt]), + Tree::Era | Tree::Num(_) | Tree::Ref(_) | Tree::Var(_) => Iter::Nil([]), + Tree::Ctr { p1, p2, .. } => Iter::Two([&mut **p1, p2]), Tree::Op { rhs, out, .. } => Iter::Two([&mut **rhs, out]), - Tree::Mat { arms, out } => Iter::Two([&mut **arms, out]), + Tree::Switch { arms, out } => Iter::Two([&mut **arms, out]), } } @@ -172,8 +167,8 @@ impl Tree { /// This function can be called multiple times with many trees to /// ensure that `fresh` does not conflict with any of them. pub(crate) fn ensure_no_conflicts(&self, fresh: &mut usize) { - if let Tree::Var { nam } = self { - if let Some(var_num) = var_to_num(nam) { + if let Tree::Var(name) = self { + if let Some(var_num) = var_to_num(name) { *fresh = (*fresh).max(var_num); } } @@ -186,13 +181,12 @@ impl Clone for Tree { fn clone(&self) -> Tree { maybe_grow(|| match self { Tree::Era => Tree::Era, - Tree::Int { val } => Tree::Int { val: *val }, - Tree::F32 { val } => Tree::F32 { val: *val }, - Tree::Ref { nam } => Tree::Ref { nam: nam.clone() }, - Tree::Ctr { lab, lft, rgt } => Tree::Ctr { lab: *lab, lft: lft.clone(), rgt: rgt.clone() }, - Tree::Op { op, rhs, out } => Tree::Op { op: *op, rhs: rhs.clone(), out: out.clone() }, - Tree::Mat { arms, out } => Tree::Mat { arms: arms.clone(), out: out.clone() }, - Tree::Var { nam } => Tree::Var { nam: nam.clone() }, + Tree::Num(num) => Tree::Num(*num), + Tree::Ref(name) => Tree::Ref(name.clone()), + Tree::Ctr { lab, p1, p2 } => Tree::Ctr { lab: *lab, p1: p1.clone(), p2: p2.clone() }, + Tree::Op { rhs, out } => Tree::Op { rhs: rhs.clone(), out: out.clone() }, + Tree::Switch { arms, out } => Tree::Switch { arms: arms.clone(), out: out.clone() }, + Tree::Var(name) => Tree::Var(name.clone()), }) } } @@ -253,17 +247,17 @@ impl fmt::Display for Tree { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { maybe_grow(move || match self { Tree::Era => write!(f, "*"), - Tree::Ctr { lab, lft, rgt } => match lab { - 0 => write!(f, "({lft} {rgt})"), - 1 => write!(f, "[{lft} {rgt}]"), - _ => write!(f, "{{{lab} {lft} {rgt}}}"), + Tree::Ctr { lab, p1, p2 } => match lab { + 0 => write!(f, "({p1} {p2})"), + 1 => write!(f, "{{{p1} {p2}}}"), + _ if lab % 2 == 0 => write!(f, "#{}({p1} {p2})", lab / 2), + _ => write!(f, "#{}{{{p1} {p2}}}", lab / 2), }, - Tree::Var { nam } => write!(f, "{nam}"), - Tree::Ref { nam } => write!(f, "@{nam}"), - Tree::Int { val } => write!(f, "#{val}"), - Tree::F32 { val } => write!(f, "#{:?}", val.0), - Tree::Op { op, rhs, out } => write!(f, "<{op} {rhs} {out}>"), - Tree::Mat { arms, out } => write!(f, "?<{arms} {out}>"), + Tree::Var(name) => write!(f, "{name}"), + Tree::Ref(name) => write!(f, "@{name}"), + Tree::Num(val) => write!(f, "{val}"), + Tree::Op { rhs, out } => write!(f, "$({rhs} {out})"), + Tree::Switch { arms, out } => write!(f, "?({arms} {out})"), }) } } @@ -278,15 +272,15 @@ fn test_tree_drop() { let mut long_tree = Tree::Era; let mut cursor = &mut long_tree; for _ in 0 .. 100_000 { - *cursor = Tree::Ctr { lab: 0, lft: Box::new(Tree::Era), rgt: Box::new(Tree::Era) }; - let Tree::Ctr { lft, .. } = cursor else { unreachable!() }; - cursor = lft; + *cursor = Tree::Ctr { lab: 0, p1: Box::new(Tree::Era), p2: Box::new(Tree::Era) }; + let Tree::Ctr { p1, .. } = cursor else { unreachable!() }; + cursor = p1; } drop(long_tree); let mut big_tree = Tree::Era; for _ in 0 .. 16 { - big_tree = Tree::Ctr { lab: 0, lft: Box::new(big_tree.clone()), rgt: Box::new(big_tree) }; + big_tree = Tree::Ctr { lab: 0, p1: Box::new(big_tree.clone()), p2: Box::new(big_tree) }; } drop(big_tree); } diff --git a/ast/src/parser.rs b/ast/src/parser.rs index a9ce0551..3b65855b 100644 --- a/ast/src/parser.rs +++ b/ast/src/parser.rs @@ -3,8 +3,9 @@ use hvm64_util::prelude::*; use alloc::collections::BTreeMap; use core::str::FromStr; -use crate::{Book, Lab, Net, Tree}; -use hvm64_util::{maybe_grow, ops::TypedOp as Op}; +use crate::{Book, Net, Tree}; +use hvm64_num::{Num, NumTag}; +use hvm64_util::maybe_grow; use TSPL::{new_parser, Parser}; @@ -47,74 +48,58 @@ impl<'i> Hvm64Parser<'i> { self.advance_one(); Ok(Tree::Era) } - // Ctr = "(" Tree Tree ")" | "[" Tree Tree "]" | "{" Int Tree Tree "}" - Some(char @ ('(' | '[' | '{')) => { + // Ctr = ("#" Num)? ("(" Tree Tree ")" | "{" Tree Tree "}") + mut char @ Some('(' | '{' | '#') => { self.advance_one(); - let lab = match char { - '(' => 0, - '[' => 1, - '{' => self.parse_u64()? as Lab, - _ => unreachable!(), + let tag = if char == Some('#') { + let tag = self.parse_u64().unwrap() as u16; + self.skip_trivia(); + char = self.advance_one(); + tag + } else { + 0 }; - let close = match char { - '(' => ")", - '[' => "]", - '{' => "}", - _ => unreachable!(), + let (close, kind) = match char { + Some('(') => (")", 0), + Some('{') => ("}", 1), + _ => self.expected("`(` or `{`")?, }; + let lab = tag * 2 + kind; self.skip_trivia(); - let lft = Box::new(self.parse_tree()?); - let rgt = Box::new(self.parse_tree()?); + let p1 = Box::new(self.parse_tree()?); + let p2 = Box::new(self.parse_tree()?); self.consume(close)?; - Ok(Tree::Ctr { lab, lft, rgt }) + Ok(Tree::Ctr { lab, p1, p2 }) } // Ref = "@" Name Some('@') => { self.advance_one(); self.skip_trivia(); - let nam = self.parse_name()?; - Ok(Tree::Ref { nam }) - } - // Int = "#" [-] Int - // F32 = "#" [-] ( Int "." Int | "NaN" | "inf" ) - Some('#') => { - self.advance_one(); - let is_neg = self.consume("-").is_ok(); - let num = self.take_while(|c| c.is_alphanumeric() || c == '.'); - - if num.contains('.') || num.contains("NaN") || num.contains("inf") { - let mut val: f32 = num.parse().map_err(|err| format!("{err:?}"))?; - if is_neg { - val = -val; - } - Ok(Tree::F32 { val: val.into() }) - } else { - let mut val: i64 = parse_int(num)? as i64; - if is_neg { - val = -val; - } - Ok(Tree::Int { val }) - } + let name = self.parse_name()?; + Ok(Tree::Ref(name)) } - // Op = "<" Op Tree Tree ">" - Some('<') => { - self.advance_one(); - let op = self.parse_op()?; + // Op = "$(" Tree Tree ")" + Some('$') => { + self.consume("$(")?; let rhs = Box::new(self.parse_tree()?); let out = Box::new(self.parse_tree()?); - self.consume(">")?; - Ok(Tree::Op { op, rhs, out }) + self.consume(")")?; + Ok(Tree::Op { rhs, out }) } - // Mat = "?<" Tree Tree ">" + // Switch = "?(" Tree Tree ")" Some('?') => { - self.consume("?<")?; + self.consume("?(")?; let arms = Box::new(self.parse_tree()?); let out = Box::new(self.parse_tree()?); - self.consume(">")?; - Ok(Tree::Mat { arms, out }) + self.consume(")")?; + Ok(Tree::Switch { arms, out }) + } + Some('0' ..= '9' | '+' | '-' | '[') => { + let num = self.parse_num()?; + Ok(Tree::Num(num)) } // Var = Name - _ => Ok(Tree::Var { nam: self.parse_name()? }), + _ => Ok(Tree::Var(self.parse_name()?)), } }) } @@ -128,21 +113,54 @@ impl<'i> Hvm64Parser<'i> { Ok(name.to_owned()) } - /// See `ops.rs` for the available operators. - fn parse_op(&mut self) -> Result { - let op = self.take_while(|c| c.is_alphanumeric() || ".+-=*/%<>|&^!?$".contains(c)); - op.parse().map_err(|_| format!("Unknown operator: {op:?}")) + fn parse_num(&mut self) -> Result { + self.skip_trivia(); + + if self.peek_one() != Some('[') { + return self.parse_num_lit(); + } + + self.consume("[")?; + + let Some(op) = NumTag::from_str_prefix(&self.input[self.index ..]) else { self.expected("operator")? }; + self.advance_many(op.as_str().len()); + + self.skip_trivia(); + + if op.is_ty() || self.peek_one() == Some(']') { + self.consume("]")?; + return Ok(Num::new_sym(op)); + } + + let lhs = self.parse_num_lit()?; + + self.consume("]")?; + + Ok(Num::operate_unary(op, lhs)) } -} -/// Parses an unsigned integer with an optional radix prefix. -fn parse_int(input: &str) -> Result { - if let Some(rest) = input.strip_prefix("0x") { - u64::from_str_radix(rest, 16).map_err(|err| format!("{err:?}")) - } else if let Some(rest) = input.strip_prefix("0b") { - u64::from_str_radix(rest, 2).map_err(|err| format!("{err:?}")) - } else { - input.parse::().map_err(|err| format!("{err:?}")) + fn parse_num_lit(&mut self) -> Result { + let num = self.take_while(|x| x.is_alphanumeric() || x == '+' || x == '-' || x == '.'); + if num.contains('.') || num.contains("inf") || num.contains("NaN") { + let val: f32 = num.parse().map_err(|err| format!("{err:?}"))?; + Ok(Num::new_f24(val)) + } else if num.starts_with('+') || num.starts_with('-') { + let val = Self::parse_int(&num[1 ..])? as i32; + Ok(Num::new_i24(if num.starts_with('-') { -val } else { val })) + } else { + let val = Self::parse_int(num)? as u32; + Ok(Num::new_u24(val)) + } + } + + fn parse_int(input: &str) -> Result { + if let Some(rest) = input.strip_prefix("0x") { + u64::from_str_radix(rest, 16).map_err(|err| format!("{err:?}")) + } else if let Some(rest) = input.strip_prefix("0b") { + u64::from_str_radix(rest, 2).map_err(|err| format!("{err:?}")) + } else { + input.parse::().map_err(|err| format!("{err:?}")) + } } } diff --git a/cspell.json b/cspell.json index 66d1030c..636c14c9 100644 --- a/cspell.json +++ b/cspell.json @@ -36,6 +36,7 @@ "oper", "outdir", "plog", + "powf", "powi", "ptrs", "rchunks", diff --git a/examples/arithmetic.hvm b/examples/arithmetic.hvm index d8f05676..9916eab2 100644 --- a/examples/arithmetic.hvm +++ b/examples/arithmetic.hvm @@ -1,9 +1,9 @@ -@add = (<+ a b> (a b)) -@div = ( (a b)) -@main = ({3 a b} ({5 c d} [e f])) +@add = ($([+] $(a b)) (a b)) +@div = ($([/] $(a b)) (a b)) +@main = (#1{a b} (#2{c d} {e f})) & @mod ~ (b (d f)) & @div ~ (a (c e)) -@mod = (<% a b> (a b)) -@mul = (<* a b> (a b)) -@sub = (<- a b> (a b)) +@mod = ($([%] $(a b)) (a b)) +@mul = ($([*] $(a b)) (a b)) +@sub = ($([-] $(a b)) (a b)) diff --git a/examples/church_encoding/church.hvm b/examples/church_encoding/church.hvm index 3d0985da..e305a076 100644 --- a/examples/church_encoding/church.hvm +++ b/examples/church_encoding/church.hvm @@ -1,8 +1,8 @@ -@S = ((a (b c)) ({3 (c d) a} (b d))) +@S = ((a (b c)) (#1{(c d) a} (b d))) @Z = (* (a a)) -@add = ((a (b c)) ((d (e b)) ({9 a d} (e c)))) -@c2 = ({5 (a b) (c a)} (c b)) -@c3 = ({7 (a b) {7 (c a) (d c)}} (d b)) +@add = ((a (b c)) ((d (e b)) (#4{a d} (e c)))) +@c2 = (#2{(a b) (c a)} (c b)) +@c3 = (#3{(a b) #3{(c a) (d c)}} (d b)) @c4 = a & @S ~ (b a) & @S ~ (c b) diff --git a/examples/lambda_calculus/hoas.hvm b/examples/lambda_calculus/hoas.hvm index d0e931ab..48ef052d 100644 --- a/examples/lambda_calculus/hoas.hvm +++ b/examples/lambda_calculus/hoas.hvm @@ -10,20 +10,20 @@ & @App ~ (a (c d)) @C2 = a & @Lam ~ (@C2$S0 a) -@C2$S0 = ({3 a b} c) +@C2$S0 = (#1{a b} c) & @Lam ~ ((d e) c) & @App ~ (a (f e)) & @App ~ (b (d f)) @C3 = a & @Lam ~ (@C3$S0 a) -@C3$S0 = ({5 a {5 b c}} d) +@C3$S0 = (#2{a #2{b c}} d) & @Lam ~ ((e f) d) & @App ~ (a (g f)) & @App ~ (b (h g)) & @App ~ (c (e h)) @C4 = a & @Lam ~ (@C4$S0 a) -@C4$S0 = ({7 a {7 b {7 c d}}} e) +@C4$S0 = (#3{a #3{b #3{c d}}} e) & @Lam ~ ((f g) e) & @App ~ (a (h g)) & @App ~ (b (i h)) @@ -31,7 +31,7 @@ & @App ~ (d (f j)) @C6 = a & @Lam ~ (@C6$S0 a) -@C6$S0 = ({9 a {9 b {9 c {9 d {9 e f}}}}} g) +@C6$S0 = (#4{a #4{b #4{c #4{d #4{e f}}}}} g) & @Lam ~ ((h i) g) & @App ~ (a (j i)) & @App ~ (b (k j)) @@ -41,7 +41,7 @@ & @App ~ (f (h n)) @C8 = a & @Lam ~ (@C8$S0 a) -@C8$S0 = ({11 a {11 b {11 c {11 d {11 e {11 f g}}}}}} h) +@C8$S0 = (#5{a #5{b #5{c #5{d #5{e #5{f g}}}}}} h) & @Lam ~ ((i j) h) & @App ~ (a (k j)) & @App ~ (b (l k)) @@ -53,14 +53,14 @@ @CS = a & @Lam ~ (@CS$S0 a) @CS$S0 = (a b) -& @Lam ~ (({13 c d} e) b) +& @Lam ~ ((#6{c d} e) b) & @Lam ~ ((f g) e) & @App ~ (c (h g)) & @App ~ (i (f h)) & @App ~ (a (d i)) @FOO = a & @Lam ~ (@FOO$S0 a) -@FOO$S0 = ({15 a b} c) +@FOO$S0 = (#7{a b} c) & @App ~ (a (b c)) @False = a & @Lam ~ (@False$S0 a) diff --git a/examples/machine_u32/num_add.hvm b/examples/machine_u32/num_add.hvm index 5862e9f4..e3b6a0f9 100644 --- a/examples/machine_u32/num_add.hvm +++ b/examples/machine_u32/num_add.hvm @@ -1,4 +1,4 @@ -@add = (<+ a b> (a b)) +@add = ($([+] $(a b)) (a b)) @main = a -& @add ~ (#123 (#100 a)) +& @add ~ (123 (100 a)) diff --git a/examples/machine_u32/num_match.hvm b/examples/machine_u32/num_match.hvm index 15c12302..ff0ffdf6 100644 --- a/examples/machine_u32/num_match.hvm +++ b/examples/machine_u32/num_match.hvm @@ -1,5 +1,5 @@ @main = a -& @pred ~ (#10 a) -@pred = (?<(a b) d> d) -& (a b) ~ (#0 (c c)) +& @pred ~ (10 a) +@pred = (?((a b) d) d) +& (a b) ~ (0 (c c)) diff --git a/examples/sort/bitonic/bitonic_sort_lam.hvm b/examples/sort/bitonic/bitonic_sort_lam.hvm index 89601038..f6d54979 100644 --- a/examples/sort/bitonic/bitonic_sort_lam.hvm +++ b/examples/sort/bitonic/bitonic_sort_lam.hvm @@ -3,28 +3,28 @@ @down = ((@down$S0 (@down$S1 a)) a) @down$S0 = (a (* b)) & @Leaf ~ (a b) -@down$S1 = (a (b ({3 c d} e))) +@down$S1 = (a (b (#1{c d} e))) & @Node ~ (f (g e)) & @flow ~ (b (d g)) & @flow ~ (a (c f)) @flow = ((@flow$S0 (@flow$S1 a)) a) @flow$S0 = (a (* b)) & @Leaf ~ (a b) -@flow$S1 = (a (b ({5 c d} e))) +@flow$S1 = (a (b (#2{c d} e))) & @down ~ (f (d e)) & @warp ~ (a (b (c f))) -@gen = (?<(a b) c> c) +@gen = (?((a b) c) c) & (a b) ~ (@gen$S0 @gen$S1) @gen$S0 = (a b) & @Leaf ~ (a b) -@gen$S1 = ({7 a b} ({9 <* #2 c> <* #2 <+ #1 d>>} e)) +@gen$S1 = (#3{a b} (#4{$([*2] c) $([*2] $([+1] d))} e)) & @Node ~ (f (g e)) & @gen ~ (b (d g)) & @gen ~ (a (c f)) @join = ((@join$S1 (@join$S6 a)) a) -@join$S0 = (* #0) +@join$S0 = (* 0) @join$S1 = (* @join$S0) -@join$S2 = (* #0) +@join$S2 = (* 0) @join$S3 = (* @join$S2) @join$S4 = (* @join$S3) @join$S5 = (a (b (c (d e)))) @@ -34,9 +34,9 @@ @join$S6 = (a (b ((@join$S4 (@join$S5 (a (b c)))) c))) @main = a & @sum ~ (b a) -& @sort ~ (c (#0 b)) +& @sort ~ (c (0 b)) & @rev ~ (d c) -& @gen ~ (#10 (#0 d)) +& @gen ~ (10 (0 d)) @rev = ((@rev$S0 (@rev$S1 a)) a) @rev$S0 = (a b) & @Leaf ~ (a b) @@ -50,13 +50,13 @@ @sort$S1 = (a (b (c d))) & @flow ~ (e (c d)) & @Node ~ (f (g e)) -& @sort ~ (b (#1 g)) -& @sort ~ (a (#0 f)) +& @sort ~ (b (1 g)) +& @sort ~ (a (0 f)) @sum = (((a a) (@sum$S0 b)) b) @sum$S0 = (a (b c)) -& @sum ~ (a <+ d c>) +& @sum ~ (a $([+] $(d c))) & @sum ~ (b d) -@swap = (?<(a b) c> c) +@swap = (?((a b) c) c) & (a b) ~ (@swap$S0 @swap$S2) @swap$S0 = (a (b c)) & @Node ~ (a (b c)) @@ -64,12 +64,12 @@ & @Node ~ (b (a c)) @swap$S2 = (* @swap$S1) @warp = ((@warp$S5 (@warp$S11 a)) a) -@warp$S0 = ({11 a b} ({13 <> a <^ c d>> e} (c f))) +@warp$S0 = (#5{a b} (#6{$([>] $(a $([^] $(c d)))) e} (c f))) & @swap ~ (d (g (h f))) & @Leaf ~ (b h) & @Leaf ~ (e g) -@warp$S1 = (* #0) -@warp$S10 = (a (b (c (d ({15 e f} g))))) +@warp$S1 = (* 0) +@warp$S10 = (a (b (c (d (#7{e f} g))))) & @join ~ (h (i g)) & @warp ~ (d (b (f i))) & @warp ~ (c (a (e h))) @@ -78,7 +78,7 @@ @warp$S3 = (* @warp$S2) @warp$S4 = (* @warp$S3) @warp$S5 = (a ((@warp$S0 (@warp$S4 (a b))) b)) -@warp$S6 = (* #0) +@warp$S6 = (* 0) @warp$S7 = (* @warp$S6) @warp$S8 = (* @warp$S7) @warp$S9 = (* @warp$S8) diff --git a/examples/sort/merge/merge_sort.hvm b/examples/sort/merge/merge_sort.hvm index 5f636967..aa3e1823 100644 --- a/examples/sort/merge/merge_sort.hvm +++ b/examples/sort/merge/merge_sort.hvm @@ -1,29 +1,29 @@ -@Leaf = (a {4 {4 a b} {4 * b}}) -@List.cons = (a (b {2 {2 a {2 b c}} {2 * c}})) -@List.nil = {2 * {2 a a}} -@Node = (a (b {4 * {4 {4 a {4 b c}} c}})) +@Leaf = (a #2(#2(a b) #2(* b))) +@List.cons = (a (b #1(#1(a #1(b c)) #1(* c)))) +@List.nil = #1(* #1(a a)) +@Node = (a (b #2(* #2(#2(a #2(b c)) c)))) @main = a & @sum ~ (b a) & @sort ~ (c b) -& @range ~ (#2 (#0 c)) +& @range ~ (2 (0 c)) @merge = (((a a) (@merge$S5 b)) b) @merge$S0 = (a (b c)) & @List.cons ~ (a (b c)) @merge$S1 = (a (b (c ((c (a (b d))) d)))) @merge$S2 = (a (b (c ((a (b (c d))) d)))) @merge$S3 = (* @merge$S2) -@merge$S4 = ({3 a b} (c ({5 << a ?<(d e) f>> g} (h i)))) +@merge$S4 = (#1{a b} (c (#2{$([<] $(a ?((d e) f))) g} (h i)))) & (d e) ~ (@merge$S1 @merge$S3) & ((j ((k k) (l m))) m) ~ (f (((n o) ((h p) ((c q) o))) i)) & @merge ~ (p (q n)) & @List.cons ~ (b l) & @List.cons ~ (g j) @merge$S5 = (a (b ((@merge$S0 (@merge$S4 (a (b c)))) c))) -@range = (?<(a b) c> c) +@range = (?((a b) c) c) & (a b) ~ (@range$S0 @range$S1) @range$S0 = (a b) & @Leaf ~ (a b) -@range$S1 = ({7 a b} ({9 <* #2 <+ #1 c>> <* #2 d>} e)) +@range$S1 = (#3{a b} (#4{$([*2] $([+1] c)) $([*2] d)} e)) & @Node ~ (f (g e)) & @range ~ (b (d g)) & @range ~ (a (c f)) @@ -34,7 +34,7 @@ & @merge ~ (d (e c)) & @sort ~ (b e) & @sort ~ (a d) -@sum = ((#0 (@sum$S0 a)) a) -@sum$S0 = (<+ a b> (c b)) +@sum = ((0 (@sum$S0 a)) a) +@sum$S0 = ($([+] $(a b)) (c b)) & @sum ~ (c a) diff --git a/examples/sort/radix/radix_sort_ctr.hvm b/examples/sort/radix/radix_sort_ctr.hvm index 036fe31b..7fb5ce30 100644 --- a/examples/sort/radix/radix_sort_ctr.hvm +++ b/examples/sort/radix/radix_sort_ctr.hvm @@ -5,10 +5,10 @@ @Single = (a (* ((a b) (* b)))) @Used = (* @Used$C0) @Used$C0 = (a (* a)) -@gen = (?<(@gen$C0 @gen$C1) a> a) +@gen = (?((@gen$C0 @gen$C1) a) a) @gen$C0 = (a b) & @Single ~ (a b) -@gen$C1 = ({7 a b} (<<< #1 {9 c <| #1 d>}> e)) +@gen$C1 = (#3{a b} ($([:<<1] #4{c $([|1] d)}) e)) & @Concat ~ (f (g e)) & @gen ~ (b (d g)) & @gen ~ (a (c f)) @@ -16,7 +16,7 @@ & @sum ~ (b a) & @sort ~ (c b) & @rev ~ (d c) -& @gen ~ (#20 (#0 d)) +& @gen ~ (20 (0 d)) @merge = (((a a) (@merge$C2 (@merge$C7 (b c)))) (b c)) @merge$C0 = (* *) @merge$C1 = (* @merge$C0) @@ -30,7 +30,7 @@ & @merge ~ (d (b g)) & @merge ~ (c (a f)) @merge$C7 = (a (b ((@merge$C3 (@merge$C5 (@merge$C6 (a (b c))))) c))) -@radix = ({3 <& #8388608 a> {3 <& #4194304 b> {3 <& #2097152 c> {3 <& #1048576 d> {3 <& #524288 e> {3 <& #262144 f> {3 <& #131072 g> {3 <& #65536 h> {3 <& #32768 i> {3 <& #16384 j> {3 <& #8192 k> {3 <& #4096 l> {3 <& #2048 m> {3 <& #1024 n> {3 <& #512 o> {3 <& #256 p> {3 <& #128 q> {3 <& #64 r> {3 <& #32 s> {3 <& #16 t> {3 <& #8 u> {3 <& #4 v> {3 <& #2 w> <& #1 x>}}}}}}}}}}}}}}}}}}}}}}} y) +@radix = (#1{$([&8388608] a) #1{$([&4194304] b) #1{$([&2097152] c) #1{$([&1048576] d) #1{$([&524288] e) #1{$([&262144] f) #1{$([&131072] g) #1{$([&65536] h) #1{$([&32768] i) #1{$([&16384] j) #1{$([&8192] k) #1{$([&4096] l) #1{$([&2048] m) #1{$([&1024] n) #1{$([&512] o) #1{$([&256] p) #1{$([&128] q) #1{$([&64] r) #1{$([&32] s) #1{$([&16] t) #1{$([&8] u) #1{$([&4] v) #1{$([&2] w) $([&1] x)}}}}}}}}}}}}}}}}}}}}}}} y) & @swap ~ (a (z (@Free y))) & @swap ~ (b (ab (@Free z))) & @swap ~ (c (bb (@Free ab))) @@ -63,13 +63,13 @@ & @rev ~ (a e) & @rev ~ (b d) @sort = (a b) -& @to_arr ~ (c (#0 b)) +& @to_arr ~ (c (0 b)) & @to_map ~ (a c) -@sum = ((#0 ((a a) (@sum$C0 b))) b) +@sum = ((0 ((a a) (@sum$C0 b))) b) @sum$C0 = (a (b c)) -& @sum ~ (a <+ d c>) +& @sum ~ (a $([+] $(d c))) & @sum ~ (b d) -@swap = (?<(@swap$C0 @swap$C2) a> a) +@swap = (?((@swap$C0 @swap$C2) a) a) @swap$C0 = (a (b c)) & @Node ~ (a (b c)) @swap$C1 = (a (b c)) @@ -79,7 +79,7 @@ @to_arr$C0 = (* @Empty) @to_arr$C1 = (a b) & @Single ~ (a b) -@to_arr$C2 = (a (b ({5 <* #2 c> <* #2 <+ #1 d>>} e))) +@to_arr$C2 = (a (b (#2{$([*2] c) $([*2] $([+1] d))} e))) & @Concat ~ (f (g e)) & @to_arr ~ (b (d g)) & @to_arr ~ (a (c f)) diff --git a/examples/sort/radix/radix_sort_lam.hvm b/examples/sort/radix/radix_sort_lam.hvm index 85359c30..f6f99fa5 100644 --- a/examples/sort/radix/radix_sort_lam.hvm +++ b/examples/sort/radix/radix_sort_lam.hvm @@ -5,11 +5,11 @@ @Single = (a (* ((a b) (* b)))) @Used = (* @Used$S0) @Used$S0 = (a (* a)) -@gen = (?<(a b) c> c) +@gen = (?((a b) c) c) & (a b) ~ (@gen$S0 @gen$S1) @gen$S0 = (a b) & @Single ~ (a b) -@gen$S1 = ({7 a b} (<<< #1 {9 c <| #1 d>}> e)) +@gen$S1 = (#3{a b} ($([:<<1] #4{c $([|1] d)}) e)) & @Concat ~ (f (g e)) & @gen ~ (b (d g)) & @gen ~ (a (c f)) @@ -17,24 +17,24 @@ & @sum ~ (b a) & @sort ~ (c b) & @rev ~ (d c) -& @gen ~ (#20 (#0 d)) +& @gen ~ (20 (0 d)) @merge = ((@merge$S1 (@merge$S4 (@merge$S9 a))) a) @merge$S0 = (a (b c)) & @Node ~ (a (b c)) @merge$S1 = ((@Free (@Used (@merge$S0 a))) a) -@merge$S2 = (* #0) +@merge$S2 = (* 0) @merge$S3 = (* @merge$S2) @merge$S4 = ((@Used (@Used (@merge$S3 a))) a) @merge$S5 = (a (b c)) & @Node ~ (a (b c)) -@merge$S6 = (* #0) +@merge$S6 = (* 0) @merge$S7 = (* @merge$S6) @merge$S8 = (a (b (c (d e)))) & @Node ~ (f (g e)) & @merge ~ (d (b g)) & @merge ~ (c (a f)) @merge$S9 = (a (b ((@merge$S5 (@merge$S7 (@merge$S8 (a (b c))))) c))) -@radix = ({3 <& #8388608 a> {3 <& #4194304 b> {3 <& #2097152 c> {3 <& #1048576 d> {3 <& #524288 e> {3 <& #262144 f> {3 <& #131072 g> {3 <& #65536 h> {3 <& #32768 i> {3 <& #16384 j> {3 <& #8192 k> {3 <& #4096 l> {3 <& #2048 m> {3 <& #1024 n> {3 <& #512 o> {3 <& #256 p> {3 <& #128 q> {3 <& #64 r> {3 <& #32 s> {3 <& #16 t> {3 <& #8 u> {3 <& #4 v> {3 <& #2 w> <& #1 x>}}}}}}}}}}}}}}}}}}}}}}} y) +@radix = (#1{$([&8388608] a) #1{$([&4194304] b) #1{$([&2097152] c) #1{$([&1048576] d) #1{$([&524288] e) #1{$([&262144] f) #1{$([&131072] g) #1{$([&65536] h) #1{$([&32768] i) #1{$([&16384] j) #1{$([&8192] k) #1{$([&4096] l) #1{$([&2048] m) #1{$([&1024] n) #1{$([&512] o) #1{$([&256] p) #1{$([&128] q) #1{$([&64] r) #1{$([&32] s) #1{$([&16] t) #1{$([&8] u) #1{$([&4] v) #1{$([&2] w) $([&1] x)}}}}}}}}}}}}}}}}}}}}}}} y) & @swap ~ (a (z (@Free y))) & @swap ~ (b (ab (@Free z))) & @swap ~ (c (bb (@Free ab))) @@ -67,13 +67,13 @@ & @rev ~ (a e) & @rev ~ (b d) @sort = (a b) -& @to_arr ~ (c (#0 b)) +& @to_arr ~ (c (0 b)) & @to_map ~ (a c) -@sum = ((#0 ((a a) (@sum$S0 b))) b) +@sum = ((0 ((a a) (@sum$S0 b))) b) @sum$S0 = (a (b c)) -& @sum ~ (a <+ d c>) +& @sum ~ (a $([+] $(d c))) & @sum ~ (b d) -@swap = (?<(a b) c> c) +@swap = (?((a b) c) c) & (a b) ~ (@swap$S0 @swap$S2) @swap$S0 = (a (b c)) & @Node ~ (a (b c)) @@ -84,7 +84,7 @@ @to_arr$S0 = (* @Empty) @to_arr$S1 = (a b) & @Single ~ (a b) -@to_arr$S2 = (a (b ({5 <* #2 <+ #1 c>> <* #2 <+ #0 d>>} e))) +@to_arr$S2 = (a (b (#2{$([*2] $([+1] c)) $([*2] $([+0] d))} e))) & @Concat ~ (f (g e)) & @to_arr ~ (b (c g)) & @to_arr ~ (a (d f)) diff --git a/foo.hvm b/foo.hvm new file mode 100644 index 00000000..ee4d5393 --- /dev/null +++ b/foo.hvm @@ -0,0 +1,3 @@ +@main = x & @foo ~ (10 x) +@foo = (?((0 @bar) x) x) +@bar = (x y) & @foo ~ (x $([<<] $(1 y))) diff --git a/host/Cargo.toml b/host/Cargo.toml index e3e28ba2..acf609ae 100644 --- a/host/Cargo.toml +++ b/host/Cargo.toml @@ -10,10 +10,11 @@ path = "src/host.rs" hvm64-util = { path = "../util", default-features = false } hvm64-ast = { path = "../ast", default-features = false } hvm64-runtime = { path = "../runtime", default-features = false } +hvm64-num = { path = "../num", default-features = false } [features] default = ["std"] -std = ["hvm64-util/std", "hvm64-ast/std", "hvm64-runtime/std"] +std = ["hvm64-util/std", "hvm64-ast/std", "hvm64-runtime/std", "hvm64-num/std"] [lints] workspace = true diff --git a/host/src/calc_labels.rs b/host/src/calc_labels.rs index 67c9140d..830f2915 100644 --- a/host/src/calc_labels.rs +++ b/host/src/calc_labels.rs @@ -96,8 +96,8 @@ pub(crate) struct LabelSets<'b>(Map<&'b str, LabelState>); impl<'b> LabelSets<'b> { pub(crate) fn into_iter(self) -> impl Iterator { - self.0.into_iter().map(|(nam, lab)| match lab { - LabelState::Done(lab) => (nam, lab), + self.0.into_iter().map(|(name, lab)| match lab { + LabelState::Done(lab) => (name, lab), _ => unreachable!(), }) } @@ -180,12 +180,12 @@ impl<'b, F: FnMut(&'b str) -> LabSet> State<'b, F> { out.add(lab); } } - if let Tree::Ref { nam } = tree { - if self.book.contains_key(nam) { - return self.visit_def(nam, depth.map(|x| x + 1), out); + if let Tree::Ref(name) = tree { + if self.book.contains_key(name) { + return self.visit_def(name, depth.map(|x| x + 1), out); } if let Some(out) = &mut out { - out.union(&(self.lookup)(nam)); + out.union(&(self.lookup)(name)); } } tree.children().map(|child| self.visit_tree(child, depth, out.as_deref_mut())).fold(usize::MAX, usize::min) diff --git a/host/src/encode.rs b/host/src/encode.rs index 7047b041..bbaecd32 100644 --- a/host/src/encode.rs +++ b/host/src/encode.rs @@ -2,8 +2,9 @@ use hvm64_util::prelude::*; use crate::Host; use hvm64_ast::{Lab, Net as AstNet, Tree}; +use hvm64_num::{Num, NumTag}; use hvm64_runtime::{Instruction, InterpretedDef, Net, Port, Trg, TrgId}; -use hvm64_util::{maybe_grow, ops::TypedOp as Op}; +use hvm64_util::maybe_grow; impl Host { /// Converts an ast net to a list of instructions to create the net. @@ -51,8 +52,8 @@ impl<'a, E: Encoder> State<'a, E> { fn visit_redex(&mut self, a: &'a Tree, b: &'a Tree) { let (port, tree) = match (a, b) { (Tree::Era, t) | (t, Tree::Era) => (Port::ERA, t), - (Tree::Ref { nam }, t) | (t, Tree::Ref { nam }) => (Port::new_ref(&self.host.defs[nam]), t), - (Tree::Int { val }, t) | (t, Tree::Int { val }) => (Port::new_int(*val), t), + (Tree::Ref(name), t) | (t, Tree::Ref(name)) => (Port::new_ref(&self.host.defs[name]), t), + (Tree::Num(num), t) | (t, Tree::Num(num)) => (Port::new_num(*num), t), (t, u) => { let (av, aw, bv, bw) = self.encoder.wires(); self.visit_tree(t, av); @@ -67,35 +68,33 @@ impl<'a, E: Encoder> State<'a, E> { fn visit_tree(&mut self, tree: &'a Tree, trg: E::Trg) { maybe_grow(move || match tree { Tree::Era => self.encoder.link_const(trg, Port::ERA), - Tree::Int { val } => self.encoder.link_const(trg, Port::new_int(*val)), - Tree::F32 { val } => self.encoder.link_const(trg, Port::new_float(val.0)), - Tree::Ref { nam } => self.encoder.link_const(trg, Port::new_ref(&self.host.defs[nam])), - Tree::Ctr { lab, lft, rgt } => { + Tree::Num(num) => self.encoder.link_const(trg, Port::new_num(*num)), + Tree::Ref(name) => self.encoder.link_const(trg, Port::new_ref(&self.host.defs[name])), + Tree::Ctr { lab, p1, p2 } => { let (l, r) = self.encoder.ctr(*lab, trg); - self.visit_tree(lft, l); - self.visit_tree(rgt, r); + self.visit_tree(p1, l); + self.visit_tree(p2, r); } - Tree::Op { op, rhs: lft, out: rgt } => match &**lft { - Tree::Int { val } => { - let o = self.encoder.op_num(*op, trg, Port::new_int(*val)); - self.visit_tree(rgt, o); + Tree::Op { rhs, out } => { + let (op, rhs, out) = match (&**rhs, &**out) { + (Tree::Num(op), Tree::Op { rhs, out }) if op.tag() == NumTag::Sym => (unsafe { op.get_sym() }, rhs, out), + _ => (NumTag::Sym, rhs, out), + }; + if let Tree::Num(num) = **rhs { + let o = self.encoder.op_num(op, trg, num); + self.visit_tree(out, o); + } else { + let (r, o) = self.encoder.op(op, trg); + self.visit_tree(rhs, r); + self.visit_tree(out, o); } - Tree::F32 { val } => { - let o = self.encoder.op_num(*op, trg, Port::new_float(val.0)); - self.visit_tree(rgt, o); - } - _ => { - let (l, r) = self.encoder.op(*op, trg); - self.visit_tree(lft, l); - self.visit_tree(rgt, r); - } - }, - Tree::Mat { arms, out } => { - let (a, o) = self.encoder.mat(trg); + } + Tree::Switch { arms, out } => { + let (a, o) = self.encoder.switch(trg); self.visit_tree(arms, a); self.visit_tree(out, o); } - Tree::Var { nam } => match self.scope.entry(nam) { + Tree::Var(name) => match self.scope.entry(name) { Entry::Occupied(e) => self.encoder.link(e.remove(), trg), Entry::Vacant(e) => { e.insert(trg); @@ -111,9 +110,9 @@ trait Encoder { fn link(&mut self, a: Self::Trg, b: Self::Trg); fn make_const(&mut self, port: Port) -> Self::Trg; fn ctr(&mut self, lab: Lab, trg: Self::Trg) -> (Self::Trg, Self::Trg); - fn op(&mut self, op: Op, trg: Self::Trg) -> (Self::Trg, Self::Trg); - fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Port) -> Self::Trg; - fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg); + fn op(&mut self, op: NumTag, trg: Self::Trg) -> (Self::Trg, Self::Trg); + fn op_num(&mut self, op: NumTag, trg: Self::Trg, rhs: Num) -> Self::Trg; + fn switch(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg); fn wires(&mut self) -> (Self::Trg, Self::Trg, Self::Trg, Self::Trg); } @@ -131,27 +130,27 @@ impl Encoder for InterpretedDef { trg } fn ctr(&mut self, lab: Lab, trg: Self::Trg) -> (Self::Trg, Self::Trg) { - let lft = self.new_trg_id(); - let rgt = self.new_trg_id(); - self.instr.push(Instruction::Ctr { lab, trg, lft, rgt }); - (lft, rgt) + let p1 = self.new_trg_id(); + let p2 = self.new_trg_id(); + self.instr.push(Instruction::Ctr { lab, trg, p1, p2 }); + (p1, p2) } - fn op(&mut self, op: Op, trg: Self::Trg) -> (Self::Trg, Self::Trg) { + fn op(&mut self, op: NumTag, trg: Self::Trg) -> (Self::Trg, Self::Trg) { let rhs = self.new_trg_id(); let out = self.new_trg_id(); self.instr.push(Instruction::Op { op, trg, rhs, out }); (rhs, out) } - fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Port) -> Self::Trg { + fn op_num(&mut self, op: NumTag, trg: Self::Trg, rhs: Num) -> Self::Trg { let out = self.new_trg_id(); self.instr.push(Instruction::OpNum { op, trg, rhs, out }); out } - fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) { - let lft = self.new_trg_id(); - let rgt = self.new_trg_id(); - self.instr.push(Instruction::Mat { trg, lft, rgt }); - (lft, rgt) + fn switch(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) { + let arms = self.new_trg_id(); + let out = self.new_trg_id(); + self.instr.push(Instruction::Switch { trg, arms, out }); + (arms, out) } fn wires(&mut self) -> (Self::Trg, Self::Trg, Self::Trg, Self::Trg) { let av = self.new_trg_id(); @@ -178,14 +177,14 @@ impl<'a> Encoder for Net<'a> { fn ctr(&mut self, lab: Lab, trg: Self::Trg) -> (Self::Trg, Self::Trg) { self.do_ctr(lab, trg) } - fn op(&mut self, op: Op, trg: Self::Trg) -> (Self::Trg, Self::Trg) { + fn op(&mut self, op: NumTag, trg: Self::Trg) -> (Self::Trg, Self::Trg) { self.do_op(op, trg) } - fn op_num(&mut self, op: Op, trg: Self::Trg, rhs: Port) -> Self::Trg { + fn op_num(&mut self, op: NumTag, trg: Self::Trg, rhs: Num) -> Self::Trg { self.do_op_num(op, trg, rhs) } - fn mat(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) { - self.do_mat(trg) + fn switch(&mut self, trg: Self::Trg) -> (Self::Trg, Self::Trg) { + self.do_switch(trg) } fn wires(&mut self) -> (Self::Trg, Self::Trg, Self::Trg, Self::Trg) { self.do_wires() diff --git a/host/src/host.rs b/host/src/host.rs index 07fc6de1..f8ff0f11 100644 --- a/host/src/host.rs +++ b/host/src/host.rs @@ -51,11 +51,11 @@ impl Host { // First, we insert empty defs into the host. Even though their instructions // are not yet set, the address of the def will not change, meaning that // `net_to_runtime_def` can safely use `Port::new_def` on them. - for (name, labs) in calculate_label_sets(book, |nam| match self.defs.get(nam) { + for (name, labs) in calculate_label_sets(book, |name| match self.defs.get(name) { Some(x) => x.labs.clone(), None => { - self.insert_def(nam, default_def(nam)); - self.defs[nam].labs.clone() + self.insert_def(name, default_def(name)); + self.defs[name].labs.clone() } }) .into_iter() @@ -66,9 +66,9 @@ impl Host { // Now that `defs` is fully populated, we can fill in the instructions of // each of the new defs. - for (nam, net) in book.iter() { + for (name, net) in book.iter() { let data = self.encode_def(net); - self.get_mut::(nam).data = data; + self.get_mut::(name).data = data; } } diff --git a/host/src/readback.rs b/host/src/readback.rs index 8198d610..1f2572ad 100644 --- a/host/src/readback.rs +++ b/host/src/readback.rs @@ -5,6 +5,7 @@ use super::{Addr, Host, Port, Tag, Wire}; use core::ops::RangeFrom; use hvm64_ast::{Net, Tree}; +use hvm64_num::{Num, NumTag}; use hvm64_util::{create_var, maybe_grow}; impl Host { @@ -54,31 +55,33 @@ impl<'a> ReadbackState<'a> { Tag::Var | Tag::Red => { // todo: resolve redirects let key = wire.unwrap().addr().min(port.addr()); - Tree::Var { - nam: create_var(match self.vars.entry(key) { - Entry::Occupied(e) => e.remove(), - Entry::Vacant(e) => *e.insert(self.var_id.next().unwrap()), - }), - } + Tree::Var(create_var(match self.vars.entry(key) { + Entry::Occupied(e) => e.remove(), + Entry::Vacant(e) => *e.insert(self.var_id.next().unwrap()), + })) } Tag::Ref if port == Port::ERA => Tree::Era, - Tag::Ref => Tree::Ref { nam: self.host.back[&port.addr()].clone() }, - Tag::Int => Tree::Int { val: port.int() }, - Tag::F32 => Tree::F32 { val: port.float().into() }, + Tag::Ref => Tree::Ref(self.host.back[&port.addr()].clone()), + Tag::Num => Tree::Num(port.num()), Tag::Op => { let op = port.op(); let node = port.traverse_node(); - Tree::Op { op, rhs: Box::new(self.read_wire(node.p1)), out: Box::new(self.read_wire(node.p2)) } + let node = Tree::Op { rhs: Box::new(self.read_wire(node.p1)), out: Box::new(self.read_wire(node.p2)) }; + if op == NumTag::Sym { + node + } else { + Tree::Op { rhs: Box::new(Tree::Num(Num::new_sym(op))), out: Box::new(node) } + } } Tag::Ctr => { let node = port.traverse_node(); - Tree::Ctr { lab: node.lab, lft: Box::new(self.read_wire(node.p1)), rgt: Box::new(self.read_wire(node.p2)) } + Tree::Ctr { lab: node.lab, p1: Box::new(self.read_wire(node.p1)), p2: Box::new(self.read_wire(node.p2)) } } - Tag::Mat => { + Tag::Switch => { let node = port.traverse_node(); let arms = self.read_wire(node.p1); let out = self.read_wire(node.p2); - Tree::Mat { arms: Box::new(arms), out: Box::new(out) } + Tree::Switch { arms: Box::new(arms), out: Box::new(out) } } }) } diff --git a/num/Cargo.toml b/num/Cargo.toml new file mode 100644 index 00000000..b94f1eb3 --- /dev/null +++ b/num/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "hvm64-num" +version.workspace = true +edition = "2021" + +[lib] +path = "src/num.rs" + +[dependencies] +hvm64-util = { path = "../util", default-features = false } + +[features] +default = ["std"] +std = ["hvm64-util/std"] + +[lints] +workspace = true diff --git a/num/src/num.rs b/num/src/num.rs new file mode 100644 index 00000000..17481e14 --- /dev/null +++ b/num/src/num.rs @@ -0,0 +1,306 @@ +#![no_std] + +use hvm64_util::prelude::*; + +use core::hint::unreachable_unchecked; + +use hvm64_util::bi_enum; + +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub struct Num { + raw: u32, +} + +bi_enum! { + #[repr(u8)] + #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub enum NumTag { + "u24": U24 = 0x00, + "i24": I24 = 0x01, + "f24": F24 = 0x02, + " ": Sym = 0x03, + "+": Add = 0x04, + "-": Sub = 0x05, + ":-": SubS = 0x06, + "*": Mul = 0x07, + "/": Div = 0x08, + ":/": DivS = 0x09, + "%": Rem = 0x0a, + ":%": RemS = 0x0b, + "&": And = 0x0c, + "|": Or = 0x0d, + "^": Xor = 0x0e, + "<<": Shl = 0x0f, + ":<<": ShlS = 0x10, + ">>": Shr = 0x11, + ":>>": ShrS = 0x12, + "=": Eq = 0x13, + "!": Ne = 0x14, + "<": Lt = 0x15, + ">": Gt = 0x16, + } +} + +impl NumTag { + #[inline(always)] + pub fn is_op(self) -> bool { + self > NumTag::Sym + } + + #[inline(always)] + pub fn is_ty(self) -> bool { + self < NumTag::Sym + } +} + +impl Num { + pub const ID: Self = Num::new_sym(NumTag::Sym); + pub const INVALID: Self = Num::new_u24(0); + pub const TAG: u8 = 3; + + pub const unsafe fn new(tag: NumTag, payload: u32) -> Self { + Self { raw: (payload << 8) | ((tag as u32) << 3) | (Self::TAG as u32) } + } + + #[inline(always)] + pub const unsafe fn from_raw(raw: u32) -> Self { + Num { raw } + } + + #[inline(always)] + pub const fn new_u24(val: u32) -> Self { + unsafe { Self::new(NumTag::U24, val) } + } + + #[inline(always)] + pub const fn new_i24(val: i32) -> Self { + unsafe { Self::new(NumTag::I24, val as u32) } + } + + #[inline] + pub fn new_f24(val: f32) -> Self { + let bits = val.to_bits(); + let mut shifted_bits = bits >> 8; + let lost_bits = bits & 0xFF; + // round ties to even + shifted_bits += u32::from(!val.is_nan()) & ((lost_bits - ((lost_bits >> 7) & !shifted_bits)) >> 7); + // ensure NaNs don't become infinities + shifted_bits |= u32::from(val.is_nan()); + unsafe { Self::new(NumTag::F24, shifted_bits) } + } + + #[inline(always)] + pub const fn new_sym(val: NumTag) -> Self { + unsafe { Self::new(NumTag::Sym, val as u32) } + } + + #[inline(always)] + pub fn raw(self) -> u32 { + self.raw + } + + #[inline(always)] + pub fn tag(self) -> NumTag { + unsafe { NumTag::from_unchecked((self.raw >> 3 & 0x1f) as u8) } + } + + #[inline(always)] + pub fn payload(self) -> u32 { + self.raw >> 8 + } + + #[inline(always)] + pub fn get_u24(self) -> u32 { + self.payload() + } + + #[inline(always)] + pub fn get_i24(self) -> i32 { + (self.raw as i32) >> 8 + } + + #[inline(always)] + pub fn get_f24(self) -> f32 { + f32::from_bits(self.raw & !0xff) + } + + #[inline(always)] + pub unsafe fn get_sym(self) -> NumTag { + unsafe { NumTag::from_unchecked(self.get_u24() as u8) } + } + + #[inline] + pub fn operate_unary(op: NumTag, num: Self) -> Self { + const U24_MAX: u32 = (1 << 24) - 1; + const U24_MIN: u32 = 0; + const I24_MAX: i32 = (1 << 23) - 1; + const I24_MIN: i32 = (-1) << 23; + + match op { + NumTag::Sym => num, + NumTag::U24 => match num.tag() { + NumTag::U24 => num, + NumTag::I24 => Num::new_u24(num.get_u24()), + NumTag::F24 => Num::new_u24((num.get_f24() as u32).clamp(U24_MIN, U24_MAX)), + _ => Self::INVALID, + }, + NumTag::I24 => match num.tag() { + NumTag::U24 => Num::new_i24(num.get_i24()), + NumTag::I24 => num, + NumTag::F24 => Num::new_i24((num.get_f24() as i32).clamp(I24_MIN, I24_MAX)), + _ => Self::INVALID, + }, + NumTag::F24 => match num.tag() { + NumTag::U24 => Num::new_f24(num.get_u24() as f32), + NumTag::I24 => Num::new_f24(num.get_i24() as f32), + NumTag::F24 => num, + _ => Self::INVALID, + }, + _ => unsafe { Self::new(op, num.payload()) }, + } + } + + #[inline] + pub fn operate_sym(a: Self, b: Self) -> Self { + let at = a.tag(); + let bt = b.tag(); + let (op, ty, a, b) = match ((at, at.is_op(), a), (bt, bt.is_op(), b)) { + ((NumTag::Sym, ..), (NumTag::Sym, ..)) => return Self::INVALID, + sym!((NumTag::Sym, _, a), (.., b)) => return Self::operate_unary(unsafe { a.get_sym() }, b), + ((_, false, _), (_, false, _)) | ((_, true, _), (_, true, _)) => return Self::INVALID, + sym!((op, true, a), (ty, false, b)) => (op, ty, a, b), + }; + match ty { + NumTag::U24 => { + let a = a.get_u24(); + let b = b.get_u24(); + match op { + NumTag::U24 | NumTag::I24 | NumTag::F24 | NumTag::Sym => unsafe { unreachable_unchecked() }, + NumTag::Add => Num::new_u24(a.wrapping_add(b)), + NumTag::Sub => Num::new_u24(a.wrapping_sub(b)), + NumTag::SubS => Num::new_u24(b.wrapping_sub(a)), + NumTag::Mul => Num::new_u24(a.wrapping_mul(b)), + NumTag::Div => Num::new_u24(a.wrapping_div(b)), + NumTag::DivS => Num::new_u24(b.wrapping_div(a)), + NumTag::Rem => Num::new_u24(a.wrapping_rem(b)), + NumTag::RemS => Num::new_u24(b.wrapping_rem(a)), + NumTag::Eq => Num::new_u24((a == b) as u32), + NumTag::Ne => Num::new_u24((a != b) as u32), + NumTag::Lt => Num::new_u24((a < b) as u32), + NumTag::Gt => Num::new_u24((a > b) as u32), + NumTag::And => Num::new_u24(a & b), + NumTag::Or => Num::new_u24(a | b), + NumTag::Xor => Num::new_u24(a ^ b), + NumTag::Shl => Num::new_u24(a.wrapping_shl(b)), + NumTag::ShlS => Num::new_u24(b.wrapping_shl(a)), + NumTag::Shr => Num::new_u24(a.wrapping_shr(b)), + NumTag::ShrS => Num::new_u24(b.wrapping_shr(a)), + } + } + NumTag::I24 => { + let a = a.get_i24(); + let b = b.get_i24(); + match op { + NumTag::U24 | NumTag::I24 | NumTag::F24 | NumTag::Sym => unsafe { unreachable_unchecked() }, + NumTag::Add => Num::new_i24(a.wrapping_add(b)), + NumTag::Sub => Num::new_i24(a.wrapping_sub(b)), + NumTag::SubS => Num::new_i24(b.wrapping_sub(a)), + NumTag::Mul => Num::new_i24(a.wrapping_mul(b)), + NumTag::Div => Num::new_i24(a.wrapping_div(b)), + NumTag::DivS => Num::new_i24(b.wrapping_div(a)), + NumTag::Rem => Num::new_i24(a.wrapping_rem(b)), + NumTag::RemS => Num::new_i24(b.wrapping_rem(a)), + NumTag::Eq => Num::new_u24((a == b) as u32), + NumTag::Ne => Num::new_u24((a != b) as u32), + NumTag::Lt => Num::new_u24((a < b) as u32), + NumTag::Gt => Num::new_u24((a > b) as u32), + NumTag::And => Num::new_i24(a & b), + NumTag::Or => Num::new_i24(a | b), + NumTag::Xor => Num::new_i24(a ^ b), + NumTag::Shl => Num::new_i24(a.wrapping_shl(b as u32)), + NumTag::ShlS => Num::new_i24(b.wrapping_shl(a as u32)), + NumTag::Shr => Num::new_i24(a.wrapping_shr(b as u32)), + NumTag::ShrS => Num::new_i24(b.wrapping_shr(a as u32)), + } + } + NumTag::F24 => { + let a = a.get_f24(); + let b = b.get_f24(); + match op { + NumTag::U24 | NumTag::I24 | NumTag::F24 | NumTag::Sym => unsafe { unreachable_unchecked() }, + NumTag::Add => Num::new_f24(a + b), + NumTag::Sub => Num::new_f24(a - b), + NumTag::SubS => Num::new_f24(b - a), + NumTag::Mul => Num::new_f24(a * b), + NumTag::Div => Num::new_f24(a / b), + NumTag::DivS => Num::new_f24(b / a), + NumTag::Rem => Num::new_f24(a % b), + NumTag::RemS => Num::new_f24(b % a), + NumTag::Eq => Num::new_u24((a == b) as u32), + NumTag::Ne => Num::new_u24((a != b) as u32), + NumTag::Lt => Num::new_u24((a < b) as u32), + NumTag::Gt => Num::new_u24((a > b) as u32), + #[cfg(feature = "std")] + NumTag::And => Num::new_f24(a.atan2(b)), + #[cfg(feature = "std")] + NumTag::Or => Num::new_f24(b.log(a)), + #[cfg(feature = "std")] + NumTag::Xor => Num::new_f24(a.powf(b)), + _ => Num::INVALID, + } + } + _ => unsafe { unreachable_unchecked() }, + } + } + + #[inline] + pub fn operate_binary(a: Self, op: NumTag, b: Self) -> Self { + if op == NumTag::Sym { + Self::operate_sym(a, b) + } else { + Self::operate_sym(Self::operate_sym(a, Num::new_sym(op)), b) + } + } +} + +macro_rules! sym { + ($a:pat, $b:pat) => { + ($a, $b) | ($b, $a) + }; +} + +use sym; + +impl fmt::Debug for Num { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{:?}", self.tag())?; + match self.tag() { + NumTag::Sym => write!(f, "({:?})", unsafe { self.get_sym() }), + NumTag::U24 => write!(f, "({:?})", self.get_u24()), + NumTag::I24 => write!(f, "({:?})", self.get_i24()), + NumTag::F24 => write!(f, "({:?})", self.get_f24()), + _ => write!(f, "(0x{:06x})", self.payload()), + } + } +} + +impl fmt::Display for Num { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self.tag() { + NumTag::Sym => write!(f, "[{}]", unsafe { self.get_sym() }), + NumTag::U24 => write!(f, "{}", self.get_u24()), + NumTag::I24 => write!(f, "{:+}", self.get_i24()), + NumTag::F24 => { + let val = self.get_f24(); + if val.is_infinite() { + if val.is_sign_positive() { write!(f, "+inf") } else { write!(f, "-inf") } + } else if val.is_nan() { + write!(f, "+NaN") + } else { + write!(f, "{val:?}") + } + } + _ => write!(f, "[{}{}]", self.tag(), self.payload()), + } + } +} diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index a9f8648c..f08f14cc 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -8,10 +8,11 @@ path = "src/runtime.rs" [dependencies] hvm64-util = { path = "../util", default-features = false } +hvm64-num = { path = "../num", default-features = false } [features] default = ["std"] -std = ["hvm64-util/std"] +std = ["hvm64-util/std", "hvm64-num/std"] trace = ["std"] [lints] diff --git a/runtime/src/def.rs b/runtime/src/def.rs index e272f01b..19fe1e43 100644 --- a/runtime/src/def.rs +++ b/runtime/src/def.rs @@ -257,24 +257,24 @@ impl AsDef for InterpretedDef { } net.link_trg_port(trgs.get_trg(trg), port.clone()) } - Instruction::Ctr { lab, trg, lft, rgt } => { - let (l, r) = net.do_ctr(lab, trgs.get_trg(trg)); - trgs.set_trg(lft, l); - trgs.set_trg(rgt, r); + Instruction::Ctr { lab, trg, p1, p2 } => { + let (t1, t2) = net.do_ctr(lab, trgs.get_trg(trg)); + trgs.set_trg(p1, t1); + trgs.set_trg(p2, t2); } Instruction::Op { op, trg, rhs, out } => { let (r, o) = net.do_op(op, trgs.get_trg(trg)); trgs.set_trg(rhs, r); trgs.set_trg(out, o); } - Instruction::OpNum { op, trg, ref rhs, out } => { - let o = net.do_op_num(op, trgs.get_trg(trg), rhs.clone()); + Instruction::OpNum { op, trg, rhs, out } => { + let o = net.do_op_num(op, trgs.get_trg(trg), rhs); trgs.set_trg(out, o); } - Instruction::Mat { trg, lft, rgt } => { - let (l, r) = net.do_mat(trgs.get_trg(trg)); - trgs.set_trg(lft, l); - trgs.set_trg(rgt, r); + Instruction::Switch { trg, arms, out } => { + let (a, o) = net.do_switch(trgs.get_trg(trg)); + trgs.set_trg(arms, a); + trgs.set_trg(out, o); } Instruction::Wires { av, aw, bv, bw } => { let (avt, awt, bvt, bwt) = net.do_wires(); diff --git a/runtime/src/instruction.rs b/runtime/src/instruction.rs index 1c100846..0f555cb5 100644 --- a/runtime/src/instruction.rs +++ b/runtime/src/instruction.rs @@ -46,24 +46,24 @@ pub enum Instruction { LinkConst { trg: TrgId, port: Port }, /// See [`Net::do_ctr`]. /// ```rust,ignore - /// let (lft, rgt) = net.do_ctr(lab, trg); + /// let (p1, p2) = net.do_ctr(lab, trg); /// ``` - Ctr { lab: Lab, trg: TrgId, lft: TrgId, rgt: TrgId }, + Ctr { lab: Lab, trg: TrgId, p1: TrgId, p2: TrgId }, /// See [`Net::do_op`]. /// ```rust,ignore /// let (rhs, out) = net.do_op(lab, trg); /// ``` - Op { op: Op, trg: TrgId, rhs: TrgId, out: TrgId }, + Op { op: NumTag, trg: TrgId, rhs: TrgId, out: TrgId }, /// See [`Net::do_op_num`]. /// ```rust,ignore /// let out = net.do_op_num(lab, trg, rhs); /// ``` - OpNum { op: Op, trg: TrgId, rhs: Port, out: TrgId }, - /// See [`Net::do_mat`]. + OpNum { op: NumTag, trg: TrgId, rhs: Num, out: TrgId }, + /// See [`Net::do_switch`]. /// ```rust,ignore - /// let (lft, rgt) = net.do_mat(trg); + /// let (arms, out) = net.do_switch(trg); /// ``` - Mat { trg: TrgId, lft: TrgId, rgt: TrgId }, + Switch { trg: TrgId, arms: TrgId, out: TrgId }, /// See [`Net::do_wires`]. /// ```rust,ignore /// let (av, aw, bv, bw) = net.do_wires(); @@ -133,19 +133,19 @@ impl<'a> Net<'a> { /// `trg ~ ` #[inline(always)] - pub fn do_op(&mut self, op: Op, trg: Trg) -> (Trg, Trg) { + pub fn do_op(&mut self, op: NumTag, trg: Trg) -> (Trg, Trg) { trace!(self.tracer, op, trg); let port = trg.target(); if port.is_num() { self.free_trg(trg); - let n = self.create_node(Op, op.swap().into()); - n.p1.wire().set_target(port); + let n = self.create_node(Op, NumTag::Sym as u16); + n.p1.wire().set_target(Port::new_num(Num::operate_unary(op, port.num()))); (Trg::port(n.p0), Trg::port(n.p2)) } else if port == Port::ERA { self.free_trg(trg); (Trg::port(Port::ERA), Trg::port(Port::ERA)) } else { - let n = self.create_node(Op, op.into()); + let n = self.create_node(Op, op as u16); self.link_trg_port(trg, n.p0); (Trg::port(n.p1), Trg::port(n.p2)) } @@ -153,34 +153,33 @@ impl<'a> Net<'a> { /// `trg ~ ` #[inline(always)] - pub fn do_op_num(&mut self, op: Op, trg: Trg, rhs: Port) -> Trg { + pub fn do_op_num(&mut self, op: NumTag, trg: Trg, rhs: Num) -> Trg { let port = trg.target(); if port.is_num() { self.rwts.oper += 1; self.free_trg(trg); - - let res = op.op(port.num(), rhs.num()); - - Trg::port(Port::new_num(if op.is_int() { Tag::Int } else { Tag::F32 }, res)) + let out = Num::operate_binary(port.num(), op, rhs); + Trg::port(Port::new_num(out)) } else if port == Port::ERA { self.free_trg(trg); Trg::port(Port::ERA) } else { - let n = self.create_node(Op, op.into()); + let n = self.create_node(Op, op as u16); self.link_trg_port(trg, n.p0); - n.p1.wire().set_target(rhs); + n.p1.wire().set_target(Port::new_num(rhs)); Trg::port(n.p2) } } /// `trg ~ ?` #[inline(always)] - pub fn do_mat(&mut self, trg: Trg) -> (Trg, Trg) { + pub fn do_switch(&mut self, trg: Trg) -> (Trg, Trg) { let port = trg.target(); - if port.tag() == Int { + if port.tag() == Num { self.rwts.oper += 1; self.free_trg(trg); - let num = port.int(); + let num = port.num(); + let num = if num.tag() == NumTag::U24 { num.get_u24() } else { 0 }; let c1 = self.create_node(Ctr, 0); if num == 0 { self.link_port_port(c1.p2, Port::ERA); @@ -189,7 +188,7 @@ impl<'a> Net<'a> { let c2 = self.create_node(Ctr, 0); self.link_port_port(c1.p1, Port::ERA); self.link_port_port(c1.p2, c2.p0); - self.link_port_port(c2.p1, Port::new_int(num - 1)); + self.link_port_port(c2.p1, Port::new_num(Num::new_u24(num - 1))); (Trg::port(c1.p0), Trg::wire(self.create_wire_to(c2.p2))) } } else if port == Port::ERA { @@ -197,7 +196,7 @@ impl<'a> Net<'a> { self.free_trg(trg); (Trg::port(Port::ERA), Trg::port(Port::ERA)) } else { - let m = self.create_node(Mat, 0); + let m = self.create_node(Switch, 0); self.link_trg_port(trg, m.p0); (Trg::port(m.p1), Trg::port(m.p2)) } @@ -209,62 +208,4 @@ impl<'a> Net<'a> { let b = a.other_half(); (Trg::port(Port::new_var(a)), Trg::wire(Wire::new(a)), Trg::port(Port::new_var(b)), Trg::wire(Wire::new(b))) } - - /// `trg ~ ?<(x (y z)) out>` - #[inline(always)] - #[allow(unused)] // TODO: emit this instruction - pub fn do_mat_con_con(&mut self, trg: Trg, out: Trg) -> (Trg, Trg, Trg) { - let port = trg.target(); - if trg.target().tag() == Int { - self.rwts.oper += 1; - self.free_trg(trg); - let num = port.int(); - if num == 0 { - (out, Trg::port(Port::ERA), Trg::port(Port::ERA)) - } else { - (Trg::port(Port::ERA), Trg::port(Port::new_int(num - 1)), out) - } - } else if port == Port::ERA { - self.link_trg_port(out, Port::ERA); - (Trg::port(Port::ERA), Trg::port(Port::ERA), Trg::port(Port::ERA)) - } else { - let m = self.create_node(Mat, 0); - let c1 = self.create_node(Ctr, 0); - let c2 = self.create_node(Ctr, 0); - self.link_port_port(m.p1, c1.p0); - self.link_port_port(c1.p2, c2.p0); - self.link_trg_port(out, m.p2); - (Trg::port(c1.p1), Trg::port(c2.p1), Trg::port(c2.p2)) - } - } - - /// `trg ~ ?<(x y) out>` - #[inline(always)] - #[allow(unused)] // TODO: emit this instruction - pub fn do_mat_con(&mut self, trg: Trg, out: Trg) -> (Trg, Trg) { - let port = trg.target(); - if trg.target().tag() == Int { - self.rwts.oper += 1; - self.free_trg(trg); - let num = port.int(); - if num == 0 { - (out, Trg::port(Port::ERA)) - } else { - let c2 = self.create_node(Ctr, 0); - c2.p1.wire().set_target(Port::new_int(num - 1)); - self.link_trg_port(out, c2.p2); - (Trg::port(Port::ERA), Trg::port(c2.p0)) - } - } else if port == Port::ERA { - self.link_trg_port(out, Port::ERA); - (Trg::port(Port::ERA), Trg::port(Port::ERA)) - } else { - let m = self.create_node(Mat, 0); - let c1 = self.create_node(Ctr, 0); - self.link_port_port(m.p1, c1.p0); - self.link_trg_port(out, m.p2); - self.link_trg_port(trg, m.p0); - (Trg::port(c1.p1), Trg::port(c1.p2)) - } - } } diff --git a/runtime/src/interact.rs b/runtime/src/interact.rs index c841e0a6..d757644b 100644 --- a/runtime/src/interact.rs +++ b/runtime/src/interact.rs @@ -10,38 +10,36 @@ impl<'a> Net<'a> { // not actually an active pair (Var | Red, _) | (_, Var | Red) => unreachable!(), // nil-nil - (Ref, Ref | Int | F32) if !a.is_skippable() => self.call(a, b), - (Ref | Int | F32, Ref) if !b.is_skippable() => self.call(b, a), - (Int | F32 | Ref, Int | F32 | Ref) => self.rwts.eras += 1, + (Ref, Ref | Num) if !a.is_skippable() => self.call(a, b), + (Ref | Num, Ref) if !b.is_skippable() => self.call(b, a), + (Num | Ref, Num | Ref) => self.rwts.eras += 1, // comm 2/2 - (Ctr, Mat) if a.lab() != 0 => self.comm22(a, b), - (Mat, Ctr) if b.lab() != 0 => self.comm22(a, b), + (Ctr, Switch) if a.lab() != 0 => self.comm22(a, b), + (Switch, Ctr) if b.lab() != 0 => self.comm22(a, b), (Ctr, Op) | (Op, Ctr) => self.comm22(a, b), (Ctr, Ctr) if a.lab() != b.lab() => self.comm22(a, b), // anni - (Mat, Mat) | (Op, Op) | (Ctr, Ctr) => self.anni2(a, b), + (Switch, Switch) | (Op, Op) | (Ctr, Ctr) => self.anni2(a, b), // comm 2/0 (Ref, Ctr) if b.lab() >= a.lab() => self.comm02(a, b), (Ctr, Ref) if a.lab() >= b.lab() => self.comm02(b, a), - (Int | F32, Ctr) => self.comm02(a, b), - (Ctr, Int | F32) => self.comm02(b, a), + (Num, Ctr) => self.comm02(a, b), + (Ctr, Num) => self.comm02(b, a), (Ref, _) if a == Port::ERA => self.comm02(a, b), (_, Ref) if b == Port::ERA => self.comm02(b, a), // deref (Ref, _) => self.call(a, b), (_, Ref) => self.call(b, a), // native ops - (Op, Int | F32) => self.op_num(a, b), - (Int | F32, Op) => self.op_num(b, a), - (Mat, Int) => self.mat_int(a, b), - (Int, Mat) => self.mat_int(b, a), + (Op, Num) => self.op_num(a, b), + (Num, Op) => self.op_num(b, a), + (Switch, Num) => self.switch_num(a, b), + (Num, Switch) => self.switch_num(b, a), // todo: what should the semantics of these be? - (Mat, F32) - | (F32, Mat) - | (Mat, Ctr) // b.lab() == 0 - | (Ctr, Mat) // a.lab() == 0 - | (Op, Mat) - | (Mat, Op) => unimplemented!("{:?}-{:?}", a.tag(), b.tag()), + (Switch, Ctr) // b.lab() == 0 + | (Ctr, Switch) // a.lab() == 0 + | (Op, Switch) + | (Switch, Op) => unimplemented!("{:?}-{:?}", a.tag(), b.tag()), } } @@ -169,7 +167,7 @@ impl<'a> Net<'a> { self.link_wire_port(b.p2, a); } - /// Interacts a number and a numeric match node. + /// Interacts a number and a numeric switch node. /// /// ```text /// | @@ -177,12 +175,12 @@ impl<'a> Net<'a> { /// | | | /// | | | /// / \ | / \ - /// a /mat\ | a /mat\ + /// a /swi\ | a /swi\ /// /_____\ | /_____\ /// | | | | | /// a1 | | a2 | a1 | | a2 /// | - /// --------------------------- | --------------------------- mat_int + /// --------------------------- | --------------------------- switch_int /// | _ _ _ _ _ /// | / \ /// | y2 | (n) y1 | @@ -200,12 +198,13 @@ impl<'a> Net<'a> { /// | /// ``` #[inline(never)] - pub fn mat_int(&mut self, a: Port, b: Port) { + pub fn switch_num(&mut self, a: Port, b: Port) { trace!(self.tracer, a, b); self.rwts.oper += 1; let a = a.consume_node(); - let b = b.int(); - if b == 0 { + let num = b.num(); + let num = if num.tag() == NumTag::U24 { num.get_u24() } else { 0 }; + if num == 0 { let x = self.create_node(Ctr, 0); trace!(self.tracer, x.p0); self.link_port_port(x.p2, Port::ERA); @@ -217,7 +216,7 @@ impl<'a> Net<'a> { trace!(self.tracer, x.p0, y.p0); self.link_port_port(x.p1, Port::ERA); self.link_port_port(x.p2, y.p0); - self.link_port_port(y.p1, Port::new_int(b - 1)); + self.link_port_port(y.p1, Port::new_num(Num::new_u24(num - 1))); self.link_wire_port(a.p2, y.p2); self.link_wire_port(a.p1, x.p0); } @@ -251,25 +250,20 @@ impl<'a> Net<'a> { #[inline(never)] pub fn op_num(&mut self, a: Port, b: Port) { trace!(self.tracer, a, b); + let op = a.op(); let a = a.consume_node(); - let op = unsafe { Op::try_from(a.lab).unwrap_unchecked() }; let a1 = a.p1.load_target(); if a1.is_num() { self.rwts.oper += 1; self.half_free(a.p1.addr()); - let out = if op.is_int() { - Port::new_num(Tag::Int, op.op(b.num(), a1.num())) - } else { - Port::new_num(Tag::F32, op.op(b.num(), a1.num())) - }; + let out = Num::operate_binary(b.num(), op, a1.num()); - self.link_wire_port(a.p2, out); + self.link_wire_port(a.p2, Port::new_num(out)); } else { - let op = op.swap(); - let x = self.create_node(Op, op.into()); + let x = self.create_node(Op, NumTag::Sym as u16); trace!(self.tracer, x.p0); - self.link_port_port(x.p1, b); + self.link_port_port(x.p1, Port::new_num(Num::operate_unary(op, b.num()))); self.link_wire_port(a.p2, x.p2); self.link_wire_port(a.p1, x.p0); } diff --git a/runtime/src/net.rs b/runtime/src/net.rs index 04cb4d4b..f63172ff 100644 --- a/runtime/src/net.rs +++ b/runtime/src/net.rs @@ -96,8 +96,8 @@ impl AsDef for ExpandDef { Tag::Red => { unreachable!() } - Tag::Ref | Tag::Int | Tag::F32 | Tag::Var => net.link_port_port(def.data.out, port), - tag @ (Tag::Op | Tag::Mat | Tag::Ctr) => { + Tag::Ref | Tag::Num | Tag::Var => net.link_port_port(def.data.out, port), + tag @ (Tag::Op | Tag::Switch | Tag::Ctr) => { let old = port.consume_node(); let new = net.create_node(tag, old.lab); net.link_port_port(def.data.out, new.p0); diff --git a/runtime/src/port.rs b/runtime/src/port.rs index dddf14f9..60143429 100644 --- a/runtime/src/port.rs +++ b/runtime/src/port.rs @@ -50,23 +50,11 @@ bi_enum! { /// Eraser nodes are represented by a null-pointer `Ref`, available as the /// constant [`Port::ERA`]. Ref = 2, - /// A `Int` port represents the principal port of an integer node. + /// A `Num` port represents the principal port of a number node. /// - /// The top 60 bits of the port are the value of this node is - /// accessible with [`Port::int`]. The type of the value may be one of - /// i8, i16, i32, u8, u16, u32, or u60. - /// - /// The 4th bit from the bottom is currently unused in this port. - Int = 3, - /// An `F32` port represents the principal port of an 32-bit floating - /// point node. - /// - /// Similarly to the [`Int`] ports, the top 60 bits are the value of - /// this node. However, since we only need 32 bits to store this floating - /// point number, the bottom 32 bits of the 60-bit value are used. - /// - /// The 4th bit from the bottom is currently unused in this port. - F32 = 4, + /// The bottom 32 bits of this port are a `Num` (including the tag bits!), + /// and can be accessed with `.num()`. + Num = 3, /// An `Op` port represents the principal port of an Op node. /// /// The label of this port is the corresponding operation, which can be @@ -76,14 +64,14 @@ bi_enum! { /// storing the targets of the wires connected to the two auxiliary ports of /// this node. Op = 5, - /// A `Mat` port represents the principal port of a Mat node. + /// A `Switch` port represents the principal port of a Switch node. /// /// The address of this port is the address of a two-word allocation, /// storing the targets of the wires connected to the two auxiliary ports of /// the node. /// /// The label of this port is currently unused and always 0. - Mat = 6, + Switch = 6, /// A `Ctr` port represents the principal port of an binary interaction /// combinator node. /// @@ -106,9 +94,8 @@ impl fmt::Debug for Port { Port::GONE => write!(f, "[GONE]"), Port::LOCK => write!(f, "[LOCK]"), _ => match self.tag() { - Int => write!(f, "[Int {}]", self.int()), - F32 => write!(f, "[F32 {:?}]", self.float()), - Var | Red | Mat => write!(f, "[{:?} {:?}]", self.tag(), self.addr()), + Num => write!(f, "[Num {:?}]", self.num()), + Var | Red | Switch => write!(f, "[{:?} {:?}]", self.tag(), self.addr()), Op | Ctr | Ref => write!(f, "[{:?} {:?} {:?}]", self.tag(), self.lab(), self.addr()), }, } @@ -140,22 +127,10 @@ impl Port { Port::new(Var, 0, addr) } - /// Creates a new [`Int`] port with a given 60-bit numeric value. - #[inline(always)] - pub fn new_int(val: i64) -> Self { - Port::new_num(Int, val as u64) - } - - /// Creates a new [`F32`] port with a given 60-bit numeric value. + /// Creates a new [`Num`] port with a given number. #[inline(always)] - pub fn new_float(val: f32) -> Self { - Port::new_num(F32, val.to_bits() as u64) - } - - /// Creates a new [`Int`] or [`F32`] port with a given 60-bit numeric value. - #[inline(always)] - pub fn new_num(tag: Tag, bits: u64) -> Self { - Port((bits << 4) | (tag as u64)) + pub fn new_num(num: Num) -> Self { + Port(num.raw() as u64) } /// Creates a new [`Ref`] port corresponding to a given definition. @@ -178,7 +153,7 @@ impl Port { /// Whether this port is numeric, either [`Int`] or [`F32`]. #[inline(always)] pub fn is_num(&self) -> bool { - self.tag() == Tag::Int || self.tag() == Tag::F32 + self.is(Tag::Num) } /// Whether this port is an [`ERA`] port. @@ -199,33 +174,16 @@ impl Port { Addr((self.0 & 0x0000_FFFF_FFFF_FFF8) as usize as _) } - /// Accesses the operation of this port; this is valid for [`Op1`] and [`Op2`] - /// ports. - #[inline(always)] - pub fn op(&self) -> Op { - unsafe { self.lab().try_into().unwrap_unchecked() } - } - - /// Accesses the integer value of this port; this is valid for [`Int`] ports. - #[inline(always)] - pub const fn int(&self) -> i64 { - self.0 as i64 >> 4 - } - - /// Accesses the float value of this port; this is valid for [`F32`] ports. + /// Accesses the operation of this port; this is valid for [`Op`] ports. #[inline(always)] - pub fn float(&self) -> f32 { - f32::from_bits(self.num() as u32) + pub fn op(&self) -> NumTag { + unsafe { NumTag::from_unchecked(self.lab() as u8) } } - /// Accesses the numeric value of this port; this is valid for [`Int`] or - /// [`F32`] ports. This is meant for numeric operations to defer - /// interpreting this port as an integer or as a float until the operation - /// type is known. + /// Accesses the integer value of this port; this is valid for [`Numb`] ports. #[inline(always)] - pub const fn num(&self) -> u64 { - // The intermediate cast to `i64` is to sign-extend during bit-shift. - ((self.0 as i64) >> 4) as u64 + pub const fn num(&self) -> Num { + unsafe { Num::from_raw(self.0 as u32) } } /// Accesses the wire leaving this port; this is valid for [`Var`] ports and @@ -261,6 +219,6 @@ impl Port { } pub fn is_full_node(&self) -> bool { - self.tag() > F32 + self.tag() > Num } } diff --git a/runtime/src/runtime.rs b/runtime/src/runtime.rs index 2112f47d..3e4968b1 100644 --- a/runtime/src/runtime.rs +++ b/runtime/src/runtime.rs @@ -22,8 +22,6 @@ use hvm64_util::prelude::*; -pub use hvm64_util::ops; - use hvm64_util::{bi_enum, deref_to, pretty_num}; use self::trace::Tracer; @@ -35,7 +33,7 @@ use core::{ mem::size_of, ops::{Add, AddAssign, Deref, DerefMut}, }; -use ops::TypedOp as Op; +use hvm64_num::{Num, NumTag}; use core::sync::atomic; diff --git a/runtime/src/trace.rs b/runtime/src/trace.rs index 6a0df5f5..2ef8c17d 100644 --- a/runtime/src/trace.rs +++ b/runtime/src/trace.rs @@ -75,7 +75,7 @@ use core::{ #[cfg(feature = "std")] use std::sync::{Mutex, Once}; -use hvm64_util::ops::TypedOp as Op; +use hvm64_num::{Num, NumTag}; use crate::{Addr, Port, Trg, Wire}; @@ -363,12 +363,21 @@ impl TraceArg for Trg { } } -impl TraceArg for Op { +impl TraceArg for Num { fn to_word(&self) -> u64 { - u16::from(*self) as u64 + self.raw() as u64 } fn from_word(word: u64) -> impl Debug { - unsafe { Op::from_unchecked(word as u16) } + unsafe { Num::from_raw(word as u32) } + } +} + +impl TraceArg for NumTag { + fn to_word(&self) -> u64 { + *self as u64 + } + fn from_word(word: u64) -> impl Debug { + unsafe { NumTag::from_unchecked(word as u8) } } } diff --git a/src/compile.rs b/src/compile.rs index 8cb80214..3fedd760 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -1,3 +1,5 @@ +use hvm64_util::prelude::*; + mod include_files; pub use include_files::*; @@ -7,8 +9,8 @@ use core::{fmt::Write, hash::Hasher}; use std::hash::DefaultHasher; use hvm64_host::Host; +use hvm64_num::Num; use hvm64_runtime::{Def, Instruction, InterpretedDef, LabSet, Port, Tag}; -use hvm64_util::prelude::*; struct DefInfo<'a> { rust_name: String, @@ -47,7 +49,8 @@ fn _compile_host(host: &Host) -> Result { extern crate alloc; -use hvm64_runtime::{{*, ops::{{TypedOp, Ty::*, Op::*}}}}; +use hvm64_runtime::*; +use hvm64_num::{{NumTag::*, Num}}; use alloc::boxed::Box; #[no_mangle] @@ -134,17 +137,17 @@ fn compile_struct(code: &mut String, host: &Host, rust_name: &str, def: &Def { writeln!(code, "net.link_trg({trg}, Trg::port({}));", compile_port(host, port)) } - Instruction::Ctr { lab, trg, lft, rgt } => { - writeln!(code, "let ({lft}, {rgt}) = net.do_ctr({lab}, {trg});") + Instruction::Ctr { lab, trg, p1, p2 } => { + writeln!(code, "let ({p1}, {p2}) = net.do_ctr({lab}, {trg});") } Instruction::Op { op, trg, rhs, out } => { writeln!(code, "let ({rhs}, {out}) = net.do_op({op:?}, {trg});") } Instruction::OpNum { op, trg, rhs, out } => { - writeln!(code, "let {out} = net.do_op_num({op:?}, {trg}, {});", compile_port(host, rhs)) + writeln!(code, "let {out} = net.do_op_num({op:?}, {trg}, {});", compile_num(*rhs)) } - Instruction::Mat { trg, lft, rgt } => { - writeln!(code, "let ({lft}, {rgt}) = net.do_mat({trg});") + Instruction::Switch { trg, arms, out } => { + writeln!(code, "let ({arms}, {out}) = net.do_mat({trg});") } Instruction::Wires { av, aw, bv, bw } => { writeln!(code, "let ({av}, {aw}, {bv}, {bw}) = net.do_wires();") @@ -163,25 +166,17 @@ fn compile_port(host: &Host, port: &Port) -> String { } else if port.tag() == Tag::Ref { let name = sanitize_name(&host.back[&port.addr()]); format!("slf.data.def_{name}.clone()") - } else if port.tag() == Tag::Int { - format!("Port::new_int({})", port.int()) - } else if port.tag() == Tag::F32 { - let float = port.float(); - - if float.is_nan() { - "Port::new_float(f32::NAN)".to_string() - } else if float.is_infinite() && float > 0.0 { - "Port::new_float(f32::INFINITY)".to_string() - } else if float.is_infinite() { - "Port::new_float(f32::NEG_INFINITY)".to_string() - } else { - format!("Port::new_float({float:?})") - } + } else if port.tag() == Tag::Num { + format!("Port::new_num({})", compile_num(port.num())) } else { unreachable!() } } +fn compile_num(num: Num) -> String { + format!("unsafe {{ Num::from_raw({}) }}", num.raw()) +} + fn compile_lab_set(labs: &LabSet) -> Result { if labs == &LabSet::ALL { return Ok("LabSet::ALL".to_owned()); diff --git a/src/compile/include_files.rs b/src/compile/include_files.rs index 4cf5931b..83c6582d 100644 --- a/src/compile/include_files.rs +++ b/src/compile/include_files.rs @@ -50,8 +50,7 @@ pub fn create_temp_hvm(host: &Host) -> Result<(), io::Error> { [workspace] resolver = "2" package.version = "0.0.0" - -members = ["util", "runtime", "gen"] +members = ["gen"] [workspace.lints] "#, @@ -67,12 +66,16 @@ edition = "2021" crate-type = ["dylib"] [dependencies] -hvm64-runtime = { path = "../runtime", default-features = false } +hvm64-runtime = { path = "../runtime" } +hvm64-num = { path = "../num" } "#, )?; fs::write(".hvm/gen/src/lib.rs", lib)?; include_files! { + crate num { + num + } crate util { lib bi_enum @@ -81,10 +84,6 @@ hvm64-runtime = { path = "../runtime", default-features = false } new_uninit_slice maybe_grow multi_iterator - ops { - num - word - } parse_abbrev_number prelude pretty_num diff --git a/src/main.rs b/src/main.rs index 79dd1f85..205e7da8 100644 --- a/src/main.rs +++ b/src/main.rs @@ -80,7 +80,7 @@ fn main() { } fn run(host: &Host, opts: RuntimeOpts, args: RunArgs) { - let mut net = Net { root: Tree::Ref { nam: args.entry_point }, redexes: vec![] }; + let mut net = Net { root: Tree::Ref(args.entry_point), redexes: vec![] }; for arg in args.args { let arg: Net = arg.parse().unwrap(); net.redexes.extend(arg.redexes); diff --git a/tests/cli.rs b/tests/cli.rs index e166ef1f..d68853d8 100644 --- a/tests/cli.rs +++ b/tests/cli.rs @@ -41,18 +41,25 @@ fn execute_hvm64(args: &[&str]) -> Result<(ExitStatus, String), Box> fn test_cli_reduce() { // Test normal-form expressions assert_snapshot!( - execute_hvm64(&["reduce", "-m", "100M", "--", "#1"]).unwrap().1, - @"#1" + execute_hvm64(&["reduce", "-m", "100M", "--", "1"]).unwrap().1, + @r###" + 1 + "### ); // Test non-normal form expressions assert_snapshot!( - execute_hvm64(&["reduce", "-m", "100M", "--", "a & #3 ~ <* #4 a>"]).unwrap().1, - @"#12" + execute_hvm64(&["reduce", "-m", "100M", "--", "a & 3 ~ $([*] $(4 a))"]).unwrap().1, + @r###" + 12 + "### ); // Test multiple expressions assert_snapshot!( - execute_hvm64(&["reduce", "-m", "100M", "--", "a & #3 ~ <* #4 a>", "a & #64 ~ "]).unwrap().1, - @"#12\n#32" + execute_hvm64(&["reduce", "-m", "100M", "--", "a & 3 ~ $([*] $(4 a))", "a & 64 ~ $([/] $(2 a))"]).unwrap().1, + @r###" + 12 + 32 + "### ); // Test loading file and reducing expression @@ -62,18 +69,23 @@ fn test_cli_reduce() { execute_hvm64(&[ "reduce", "-m", "100M", &arithmetic_program, - "--", "a & @mul ~ (#3 (#4 a))" + "--", "a & @mul ~ (3 (4 a))" ]).unwrap().1, - @"#12" + @r###" + 12 + "### ); assert_snapshot!( execute_hvm64(&[ "reduce", "-m", "100M", &arithmetic_program, - "--", "a & @mul ~ (#3 (#4 a))", "a & @div ~ (#64 (#2 a))" + "--", "a & @mul ~ (3 (4 a))", "a & @div ~ (64 (2 a))" ]).unwrap().1, - @"#12\n#32" + @r###" + 12 + 32 + "### ) } @@ -87,7 +99,9 @@ fn test_cli_run_with_args() { "run", "-m", "100M", &arithmetic_program, ]).unwrap().1, - @"({3 <% c d>} ({5 a c} [b d]))" + @r###" + (#1{$([/] $(a b)) $([%] $(c d))} (#2{a c} {b d})) + "### ); // Test partial argument passing @@ -95,9 +109,11 @@ fn test_cli_run_with_args() { execute_hvm64(&[ "run", "-m", "100M", &arithmetic_program, - "#64" + "64" ]).unwrap().1, - @"({5 <%$ #64 b>} [a b])" + @r###" + (#2{$([/64] a) $([%64] b)} {a b}) + "### ); // Test passing all arguments. @@ -105,10 +121,12 @@ fn test_cli_run_with_args() { execute_hvm64(&[ "run", "-m", "100M", &arithmetic_program, - "#64", - "#3" + "64", + "3" ]).unwrap().1, - @"[#21 #1]" + @r###" + {21 1} + "### ); } @@ -124,17 +142,17 @@ fn test_cli_transform() { &arithmetic_program, ]).unwrap().1, @r###" - @add = (<+ a b> (a b)) + @add = ($([+] $(a b)) (a b)) - @div = ( (a b)) + @div = ($([/] $(a b)) (a b)) - @main = ({3 <% c d>} ({5 a c} [b d])) + @main = (#1{$([/] $(a b)) $([%] $(c d))} (#2{a c} {b d})) - @mod = (<% a b> (a b)) + @mod = ($([%] $(a b)) (a b)) - @mul = (<* a b> (a b)) + @mul = ($([*] $(a b)) (a b)) - @sub = (<- a b> (a b)) + @sub = ($([-] $(a b)) (a b)) "### ); @@ -146,19 +164,19 @@ fn test_cli_transform() { &arithmetic_program, ]).unwrap().1, @r###" - @add = (<+ a b> (a b)) + @add = ($([+] $(a b)) (a b)) - @div = ( (a b)) + @div = ($([/] $(a b)) (a b)) - @main = ({3 a b} ({5 c d} [e f])) + @main = (#1{a b} (#2{c d} {e f})) & @mod ~ (b (d f)) & @div ~ (a (c e)) - @mod = (<% a b> (a b)) + @mod = ($([%] $(a b)) (a b)) - @mul = (<* a b> (a b)) + @mul = ($([*] $(a b)) (a b)) - @sub = (<- a b> (a b)) + @sub = ($([-] $(a b)) (a b)) "### ); } @@ -215,20 +233,20 @@ fn test_apply_tree() { @"(a a)" ); assert_snapshot!( - eval_with_args("(* #1)", &["(a a)"]), - @"#1" + eval_with_args("(* 1)", &["(a a)"]), + @"1" ); assert_snapshot!( - eval_with_args("(<+ a b> (a b))", &["#1", "#2"]), - @"#3" + eval_with_args("($([+] $(a b)) (a b))", &["1", "2"]), + @"3" ); assert_snapshot!( - eval_with_args("(<* a b> (a b))", &["#2", "#3"]), - @"#6" + eval_with_args("($([*] $(a b)) (a b))", &["2", "3"]), + @"6" ); assert_snapshot!( - eval_with_args("(<* a b> (a b))", &["#2"]), - @"(<* #2 a> a)" + eval_with_args("($([*] $(a b)) (a b))", &["2"]), + @"($([*2] a) a)" ); } @@ -247,11 +265,11 @@ fn test_cli_compile() { panic!("{:?}", "compilation failed"); }; - let (status, output) = execute_hvm64(&["run", "-i", "examples/arithmetic", "/dev/null", "#40", "#3"]).unwrap(); + let (status, output) = execute_hvm64(&["run", "-i", "examples/arithmetic", "/dev/null", "40", "3"]).unwrap(); assert_snapshot!(format_args!("{status}\n{output}"), @r###" exit status: 0 - [#13 #1] + {13 1} "###); fs::remove_file("examples/arithmetic").unwrap(); diff --git a/tests/lists.rs b/tests/lists.rs index d92edce2..e927b2e1 100644 --- a/tests/lists.rs +++ b/tests/lists.rs @@ -9,9 +9,9 @@ fn list_got(index: u32) -> Book { let code = load_file("list_put_got.hvm"); let mut book = parse_core(&code); let def = book.get_mut("GenGotIndex").unwrap(); - def.apply_tree(Tree::Ref { nam: format!("S{index}") }); + def.apply_tree(Tree::Ref(format!("S{index}"))); let def = book.get_mut("main").unwrap(); - def.apply_tree(Tree::Ref { nam: "GenGotIndex".to_string() }); + def.apply_tree(Tree::Ref("GenGotIndex".to_string())); book } @@ -19,10 +19,10 @@ fn list_put(index: u32, value: u32) -> Book { let code = load_file("list_put_got.hvm"); let mut book = parse_core(&code); let def = book.get_mut("GenPutIndexValue").unwrap(); - def.apply_tree(Tree::Ref { nam: format!("S{index}") }); - def.apply_tree(Tree::Ref { nam: format!("S{value}") }); + def.apply_tree(Tree::Ref(format!("S{index}"))); + def.apply_tree(Tree::Ref(format!("S{value}"))); let def = book.get_mut("main").unwrap(); - def.apply_tree(Tree::Ref { nam: "GenPutIndexValue".to_string() }); + def.apply_tree(Tree::Ref("GenPutIndexValue".to_string())); book } diff --git a/tests/programs/alloc_big_tree.hvm b/tests/programs/alloc_big_tree.hvm index 85cd5058..297a213f 100644 --- a/tests/programs/alloc_big_tree.hvm +++ b/tests/programs/alloc_big_tree.hvm @@ -3,33 +3,33 @@ // Church Nats @c0 = (* (a a)) @c1 = ((a R) (a R)) -@c2 = ([(b a) (a R)] (b R)) -@c3 = ([[(c b) (b a)] (a R)] (c R)) -@c4 = ([[[(d c) (c b)] (b a)] (a R)] (d R)) -@c5 = ([[[[(e d) (d c)] (c b)] (b a)] (a R)] (e R)) -@c6 = ([[[[[(f e) (e d)] (d c)] (c b)] (b a)] (a R)] (f R)) -@c7 = ([[[[[[(g f) (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (g R)) -@c8 = ([[[[[[[(h g) (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (h R)) -@c9 = ([[[[[[[[(i h) (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (i R)) -@c10 = ([[[[[[[[[(j i) (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (j R)) -@c11 = ([[[[[[[[[[(k j) (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (k R)) -@c12 = ([[[[[[[[[[[(l k) (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (l R)) -@c13 = ([[[[[[[[[[[[(m l) (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (m R)) -@c14 = ([[[[[[[[[[[[[(n m) (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (n R)) -@c15 = ([[[[[[[[[[[[[[(o n) (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (o R)) -@c16 = ([[[[[[[[[[[[[[[(p o) (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (p R)) -@c17 = ([[[[[[[[[[[[[[[[(q p) (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (q R)) -@c18 = ([[[[[[[[[[[[[[[[[(r q) (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (r R)) -@c19 = ([[[[[[[[[[[[[[[[[[(s r) (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (s R)) -@c20 = ([[[[[[[[[[[[[[[[[[[(t s) (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (t R)) -@c21 = ([[[[[[[[[[[[[[[[[[[[(u t) (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (u R)) -@c22 = ([[[[[[[[[[[[[[[[[[[[[(v u) (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (v R)) -@c23 = ([[[[[[[[[[[[[[[[[[[[[[(w v) (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (w R)) -@c24 = ([[[[[[[[[[[[[[[[[[[[[[[(x w) (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (x R)) -@c25 = ([[[[[[[[[[[[[[[[[[[[[[[[(y x) (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (y R)) -@c26 = ([[[[[[[[[[[[[[[[[[[[[[[[[(z y) (y x)] (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (z R)) +@c2 = ({(b a) (a R)} (b R)) +@c3 = ({{(c b) (b a)} (a R)} (c R)) +@c4 = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c5 = ({{{{(e d) (d c)} (c b)} (b a)} (a R)} (e R)) +@c6 = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c7 = ({{{{{{(g f) (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (g R)) +@c8 = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c9 = ({{{{{{{{(i h) (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (i R)) +@c10 = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c11 = ({{{{{{{{{{(k j) (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (k R)) +@c12 = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c13 = ({{{{{{{{{{{{(m l) (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (m R)) +@c14 = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c15 = ({{{{{{{{{{{{{{(o n) (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (o R)) +@c16 = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c17 = ({{{{{{{{{{{{{{{{(q p) (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (q R)) +@c18 = ({{{{{{{{{{{{{{{{{(r q) (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (r R)) +@c19 = ({{{{{{{{{{{{{{{{{{(s r) (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (s R)) +@c20 = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c21 = ({{{{{{{{{{{{{{{{{{{{(u t) (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (u R)) +@c22 = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c23 = ({{{{{{{{{{{{{{{{{{{{{{(w v) (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (w R)) +@c24 = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c25 = ({{{{{{{{{{{{{{{{{{{{{{{{(y x) (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (y R)) +@c26 = ({{{{{{{{{{{{{{{{{{{{{{{{{(z y) (y x)} (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (z R)) -@g_s = ({2 r0 r1} ((r0 (r1 r)) r)) +@g_s = (#1(r0 r1) ((r0 (r1 r)) r)) @g_z = (x x) @main diff --git a/tests/programs/alloc_small_tree.hvm b/tests/programs/alloc_small_tree.hvm index 805b0a47..2e897152 100644 --- a/tests/programs/alloc_small_tree.hvm +++ b/tests/programs/alloc_small_tree.hvm @@ -1,7 +1,7 @@ @Add = ((a b) (c b)) & @S ~ (c a) @Alloc = ((@Alloc$S0 (@Leaf a)) a) -@Alloc$S0 = ({3 a b} c) +@Alloc$S0 = (#1{a b} c) & @Node ~ (d (e c)) & @Alloc ~ (b e) & @Alloc ~ (a d) diff --git a/tests/programs/chained_ops.hvm b/tests/programs/chained_ops.hvm index bd32fd58..af1149d1 100644 --- a/tests/programs/chained_ops.hvm +++ b/tests/programs/chained_ops.hvm @@ -1,16 +1,16 @@ @main = a -& ({3 <* b <- c <* d e>>> {3 <* f <- #20 g>> h}} ({5 i {5 j k}} e)) ~ (#70 (#50 a)) -& #70 ~ <* k l> -& #80 ~ <+ l m> -& #10 ~ <* m <+ n d>> -& #80 ~ <+ o n> -& #70 ~ <* h o> -& #70 ~ <* j p> -& #80 ~ <+ p q> -& #10 ~ <* q c> -& #70 ~ <* i r> -& #80 ~ <+ r s> -& #10 ~ <* s <- #20 t>> -& #178 ~ <+ t f> -& #178 ~ <+ g b> +& (#1{$([*] $(b $([-] $(c $([*] $(d e)))))) #1{$([*] $(f $([:-20] g))) h}} (#2{i #2{j k}} e)) ~ (70 (50 a)) +& 70 ~ $([*] $(k l)) +& 80 ~ $([+] $(l m)) +& 10 ~ $([*] $(m $([+] $(n d)))) +& 80 ~ $([+] $(o n)) +& 70 ~ $([*] $(h o)) +& 70 ~ $([*] $(j p)) +& 80 ~ $([+] $(p q)) +& 10 ~ $([*] $(q c)) +& 70 ~ $([*] $(i r)) +& 80 ~ $([+] $(r s)) +& 10 ~ $([*] $(s $([:-20] t))) +& 178 ~ $([+] $(t f)) +& 178 ~ $([+] $(g b)) diff --git a/tests/programs/church_exp.hvm b/tests/programs/church_exp.hvm index b21108f5..53237cbe 100644 --- a/tests/programs/church_exp.hvm +++ b/tests/programs/church_exp.hvm @@ -2,59 +2,59 @@ @c0a = (* (a a)) @c1a = ((a R) (a R)) -@c2a = ([(b a) (a R)] (b R)) -@c3a = ([[(c b) (b a)] (a R)] (c R)) -@c4a = ([[[(d c) (c b)] (b a)] (a R)] (d R)) -@c5a = ([[[[(e d) (d c)] (c b)] (b a)] (a R)] (e R)) -@c6a = ([[[[[(f e) (e d)] (d c)] (c b)] (b a)] (a R)] (f R)) -@c7a = ([[[[[[(g f) (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (g R)) -@c8a = ([[[[[[[(h g) (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (h R)) -@c9a = ([[[[[[[[(i h) (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (i R)) -@c10a = ([[[[[[[[[(j i) (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (j R)) -@c11a = ([[[[[[[[[[(k j) (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (k R)) -@c12a = ([[[[[[[[[[[(l k) (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (l R)) -@c13a = ([[[[[[[[[[[[(m l) (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (m R)) -@c14a = ([[[[[[[[[[[[[(n m) (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (n R)) -@c15a = ([[[[[[[[[[[[[[(o n) (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (o R)) -@c16a = ([[[[[[[[[[[[[[[(p o) (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (p R)) -@c17a = ([[[[[[[[[[[[[[[[(q p) (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (q R)) -@c18a = ([[[[[[[[[[[[[[[[[(r q) (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (r R)) -@c19a = ([[[[[[[[[[[[[[[[[[(s r) (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (s R)) -@c20a = ([[[[[[[[[[[[[[[[[[[(t s) (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (t R)) -@c21a = ([[[[[[[[[[[[[[[[[[[[(u t) (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (u R)) -@c22a = ([[[[[[[[[[[[[[[[[[[[[(v u) (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (v R)) -@c23a = ([[[[[[[[[[[[[[[[[[[[[[(w v) (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (w R)) -@c24a = ([[[[[[[[[[[[[[[[[[[[[[[(x w) (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (x R)) -@c25a = ([[[[[[[[[[[[[[[[[[[[[[[[(y x) (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (y R)) -@c26a = ([[[[[[[[[[[[[[[[[[[[[[[[[(z y) (y x)] (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (z R)) +@c2a = ({(b a) (a R)} (b R)) +@c3a = ({{(c b) (b a)} (a R)} (c R)) +@c4a = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c5a = ({{{{(e d) (d c)} (c b)} (b a)} (a R)} (e R)) +@c6a = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c7a = ({{{{{{(g f) (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (g R)) +@c8a = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c9a = ({{{{{{{{(i h) (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (i R)) +@c10a = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c11a = ({{{{{{{{{{(k j) (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (k R)) +@c12a = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c13a = ({{{{{{{{{{{{(m l) (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (m R)) +@c14a = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c15a = ({{{{{{{{{{{{{{(o n) (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (o R)) +@c16a = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c17a = ({{{{{{{{{{{{{{{{(q p) (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (q R)) +@c18a = ({{{{{{{{{{{{{{{{{(r q) (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (r R)) +@c19a = ({{{{{{{{{{{{{{{{{{(s r) (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (s R)) +@c20a = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c21a = ({{{{{{{{{{{{{{{{{{{{(u t) (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (u R)) +@c22a = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c23a = ({{{{{{{{{{{{{{{{{{{{{{(w v) (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (w R)) +@c24a = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c25a = ({{{{{{{{{{{{{{{{{{{{{{{{(y x) (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (y R)) +@c26a = ({{{{{{{{{{{{{{{{{{{{{{{{{(z y) (y x)} (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (z R)) @c0b = (* (a a)) @c1b = ((a R) (a R)) -@c2b = ({2 (b a) (a R)} (b R)) -@c3b = ({2 {2 (c b) (b a)} (a R)} (c R)) -@c4b = ({2 {2 {2 (d c) (c b)} (b a)} (a R)} (d R)) -@c5b = ({2 {2 {2 {2 (e d) (d c)} (c b)} (b a)} (a R)} (e R)) -@c6b = ({2 {2 {2 {2 {2 (f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) -@c7b = ({2 {2 {2 {2 {2 {2 (g f) (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (g R)) -@c8b = ({2 {2 {2 {2 {2 {2 {2 (h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) -@c9b = ({2 {2 {2 {2 {2 {2 {2 {2 (i h) (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (i R)) -@c10b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 (j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) -@c11b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (k j) (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (k R)) -@c12b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) -@c13b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (m l) (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (m R)) -@c14b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) -@c15b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (o n) (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (o R)) -@c16b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) -@c17b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (q p) (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (q R)) -@c18b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (r q) (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (r R)) -@c19b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (s r) (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (s R)) -@c20b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) -@c21b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (u t) (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (u R)) -@c22b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) -@c23b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (w v) (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (w R)) -@c24b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) -@c25b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (y x) (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (y R)) -@c26b = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (z y) (y x)} (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (z R)) +@c2b = (#1((b a) (a R)) (b R)) +@c3b = (#1(#1((c b) (b a)) (a R)) (c R)) +@c4b = (#1(#1(#1((d c) (c b)) (b a)) (a R)) (d R)) +@c5b = (#1(#1(#1(#1((e d) (d c)) (c b)) (b a)) (a R)) (e R)) +@c6b = (#1(#1(#1(#1(#1((f e) (e d)) (d c)) (c b)) (b a)) (a R)) (f R)) +@c7b = (#1(#1(#1(#1(#1(#1((g f) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (g R)) +@c8b = (#1(#1(#1(#1(#1(#1(#1((h g) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (h R)) +@c9b = (#1(#1(#1(#1(#1(#1(#1(#1((i h) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (i R)) +@c10b = (#1(#1(#1(#1(#1(#1(#1(#1(#1((j i) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (j R)) +@c11b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((k j) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (k R)) +@c12b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((l k) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (l R)) +@c13b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((m l) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (m R)) +@c14b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((n m) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (n R)) +@c15b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((o n) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (o R)) +@c16b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((p o) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (p R)) +@c17b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((q p) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (q R)) +@c18b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((r q) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (r R)) +@c19b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((s r) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (s R)) +@c20b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((t s) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (t R)) +@c21b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((u t) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (u R)) +@c22b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((v u) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (v R)) +@c23b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((w v) (v u)) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (w R)) +@c24b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((x w) (w v)) (v u)) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (x R)) +@c25b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((y x) (x w)) (w v)) (v u)) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (y R)) +@c26b = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((z y) (y x)) (x w)) (w v)) (v u)) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (z R)) @main diff --git a/tests/programs/church_mul.hvm b/tests/programs/church_mul.hvm index e0ee62f9..d8ebd6f3 100644 --- a/tests/programs/church_mul.hvm +++ b/tests/programs/church_mul.hvm @@ -1,4 +1,4 @@ -@C_20 = ({3 (a b) {3 (c a) {3 (d c) {3 (e d) {3 (f e) {3 (g f) {3 (h g) {3 (i h) {3 (j i) {3 (k j) {3 (l k) {3 (m l) {3 (n m) {3 (o n) {3 (p o) {3 (q p) {3 (r q) {3 (s r) {3 (t s) (u t)}}}}}}}}}}}}}}}}}}} (u b)) +@C_20 = (#1{(a b) #1{(c a) #1{(d c) #1{(e d) #1{(f e) #1{(g f) #1{(h g) #1{(i h) #1{(j i) #1{(k j) #1{(l k) #1{(m l) #1{(n m) #1{(o n) #1{(p o) #1{(q p) #1{(r q) #1{(s r) #1{(t s) (u t)}}}}}}}}}}}}}}}}}}} (u b)) @Mult = ((a (b c)) ((d a) (d (b c)))) @main = a & @Mult ~ (@C_20 (@C_20 a)) diff --git a/tests/programs/commutation.hvm b/tests/programs/commutation.hvm index d64f3e20..d3bb5e9f 100644 --- a/tests/programs/commutation.hvm +++ b/tests/programs/commutation.hvm @@ -1 +1 @@ -@main = root & (x x) ~ [* root] +@main = root & (x x) ~ {* root} diff --git a/tests/programs/dec_bits.hvm b/tests/programs/dec_bits.hvm index c7e20547..fd445020 100644 --- a/tests/programs/dec_bits.hvm +++ b/tests/programs/dec_bits.hvm @@ -5,31 +5,31 @@ // Church Nats @c0 = (* (a a)) @c1 = ((a R) (a R)) -@c2 = ([(b a) (a R)] (b R)) -@c3 = ([[(c b) (b a)] (a R)] (c R)) -@c4 = ([[[(d c) (c b)] (b a)] (a R)] (d R)) -@c5 = ([[[[(e d) (d c)] (c b)] (b a)] (a R)] (e R)) -@c6 = ([[[[[(f e) (e d)] (d c)] (c b)] (b a)] (a R)] (f R)) -@c7 = ([[[[[[(g f) (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (g R)) -@c8 = ([[[[[[[(h g) (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (h R)) -@c9 = ([[[[[[[[(i h) (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (i R)) -@c10 = ([[[[[[[[[(j i) (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (j R)) -@c11 = ([[[[[[[[[[(k j) (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (k R)) -@c12 = ([[[[[[[[[[[(l k) (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (l R)) -@c13 = ([[[[[[[[[[[[(m l) (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (m R)) -@c14 = ([[[[[[[[[[[[[(n m) (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (n R)) -@c15 = ([[[[[[[[[[[[[[(o n) (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (o R)) -@c16 = ([[[[[[[[[[[[[[[(p o) (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (p R)) -@c17 = ([[[[[[[[[[[[[[[[(q p) (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (q R)) -@c18 = ([[[[[[[[[[[[[[[[[(r q) (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (r R)) -@c19 = ([[[[[[[[[[[[[[[[[[(s r) (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (s R)) -@c20 = ([[[[[[[[[[[[[[[[[[[(t s) (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (t R)) -@c21 = ([[[[[[[[[[[[[[[[[[[[(u t) (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (u R)) -@c22 = ([[[[[[[[[[[[[[[[[[[[[(v u) (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (v R)) -@c23 = ([[[[[[[[[[[[[[[[[[[[[[(w v) (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (w R)) -@c24 = ([[[[[[[[[[[[[[[[[[[[[[[(x w) (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (x R)) -@c25 = ([[[[[[[[[[[[[[[[[[[[[[[[(y x) (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (y R)) -@c26 = ([[[[[[[[[[[[[[[[[[[[[[[[[(z y) (y x)] (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (z R)) +@c2 = ({(b a) (a R)} (b R)) +@c3 = ({{(c b) (b a)} (a R)} (c R)) +@c4 = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c5 = ({{{{(e d) (d c)} (c b)} (b a)} (a R)} (e R)) +@c6 = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c7 = ({{{{{{(g f) (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (g R)) +@c8 = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c9 = ({{{{{{{{(i h) (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (i R)) +@c10 = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c11 = ({{{{{{{{{{(k j) (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (k R)) +@c12 = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c13 = ({{{{{{{{{{{{(m l) (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (m R)) +@c14 = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c15 = ({{{{{{{{{{{{{{(o n) (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (o R)) +@c16 = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c17 = ({{{{{{{{{{{{{{{{(q p) (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (q R)) +@c18 = ({{{{{{{{{{{{{{{{{(r q) (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (r R)) +@c19 = ({{{{{{{{{{{{{{{{{{(s r) (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (s R)) +@c20 = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c21 = ({{{{{{{{{{{{{{{{{{{{(u t) (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (u R)) +@c22 = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c23 = ({{{{{{{{{{{{{{{{{{{{{{(w v) (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (w R)) +@c24 = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c25 = ({{{{{{{{{{{{{{{{{{{{{{{{(y x) (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (y R)) +@c26 = ({{{{{{{{{{{{{{{{{{{{{{{{{(z y) (y x)} (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (z R)) @O = (xs ((xs r) (* (* r)))) @I = (xs (* ((xs r) (* r)))) diff --git a/tests/programs/dec_bits_tree.hvm b/tests/programs/dec_bits_tree.hvm index 34bc09b1..73ad92a1 100644 --- a/tests/programs/dec_bits_tree.hvm +++ b/tests/programs/dec_bits_tree.hvm @@ -5,31 +5,31 @@ // Church Nats @c0 = (* (a a)) @c1 = ((a R) (a R)) -@c2 = ([(b a) (a R)] (b R)) -@c3 = ([[(c b) (b a)] (a R)] (c R)) -@c4 = ([[[(d c) (c b)] (b a)] (a R)] (d R)) -@c5 = ([[[[(e d) (d c)] (c b)] (b a)] (a R)] (e R)) -@c6 = ([[[[[(f e) (e d)] (d c)] (c b)] (b a)] (a R)] (f R)) -@c7 = ([[[[[[(g f) (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (g R)) -@c8 = ([[[[[[[(h g) (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (h R)) -@c9 = ([[[[[[[[(i h) (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (i R)) -@c10 = ([[[[[[[[[(j i) (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (j R)) -@c11 = ([[[[[[[[[[(k j) (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (k R)) -@c12 = ([[[[[[[[[[[(l k) (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (l R)) -@c13 = ([[[[[[[[[[[[(m l) (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (m R)) -@c14 = ([[[[[[[[[[[[[(n m) (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (n R)) -@c15 = ([[[[[[[[[[[[[[(o n) (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (o R)) -@c16 = ([[[[[[[[[[[[[[[(p o) (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (p R)) -@c17 = ([[[[[[[[[[[[[[[[(q p) (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (q R)) -@c18 = ([[[[[[[[[[[[[[[[[(r q) (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (r R)) -@c19 = ([[[[[[[[[[[[[[[[[[(s r) (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (s R)) -@c20 = ([[[[[[[[[[[[[[[[[[[(t s) (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (t R)) -@c21 = ([[[[[[[[[[[[[[[[[[[[(u t) (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (u R)) -@c22 = ([[[[[[[[[[[[[[[[[[[[[(v u) (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (v R)) -@c23 = ([[[[[[[[[[[[[[[[[[[[[[(w v) (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (w R)) -@c24 = ([[[[[[[[[[[[[[[[[[[[[[[(x w) (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (x R)) -@c25 = ([[[[[[[[[[[[[[[[[[[[[[[[(y x) (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (y R)) -@c26 = ([[[[[[[[[[[[[[[[[[[[[[[[[(z y) (y x)] (x w)] (w v)] (v u)] (u t)] (t s)] (s r)] (r q)] (q p)] (p o)] (o n)] (n m)] (m l)] (l k)] (k j)] (j i)] (i h)] (h g)] (g f)] (f e)] (e d)] (d c)] (c b)] (b a)] (a R)] (z R)) +@c2 = ({(b a) (a R)} (b R)) +@c3 = ({{(c b) (b a)} (a R)} (c R)) +@c4 = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c5 = ({{{{(e d) (d c)} (c b)} (b a)} (a R)} (e R)) +@c6 = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c7 = ({{{{{{(g f) (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (g R)) +@c8 = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c9 = ({{{{{{{{(i h) (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (i R)) +@c10 = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c11 = ({{{{{{{{{{(k j) (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (k R)) +@c12 = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c13 = ({{{{{{{{{{{{(m l) (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (m R)) +@c14 = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c15 = ({{{{{{{{{{{{{{(o n) (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (o R)) +@c16 = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c17 = ({{{{{{{{{{{{{{{{(q p) (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (q R)) +@c18 = ({{{{{{{{{{{{{{{{{(r q) (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (r R)) +@c19 = ({{{{{{{{{{{{{{{{{{(s r) (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (s R)) +@c20 = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c21 = ({{{{{{{{{{{{{{{{{{{{(u t) (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (u R)) +@c22 = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c23 = ({{{{{{{{{{{{{{{{{{{{{{(w v) (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (w R)) +@c24 = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c25 = ({{{{{{{{{{{{{{{{{{{{{{{{(y x) (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (y R)) +@c26 = ({{{{{{{{{{{{{{{{{{{{{{{{{(z y) (y x)} (x w)} (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (z R)) @S = (a ((a b) (* b))) @Z = (* (a a)) @@ -51,7 +51,7 @@ @run = ((@runO (@runI (@E R))) R) @brnZ = R & @run ~ (val R) & @c10 ~ (@I (@E val)) -@brnS = ([p0 p1] (r0 r1)) & @brn ~ (p0 r0) & @brn ~ (p1 r1) +@brnS = ({p0 p1} (r0 r1)) & @brn ~ (p0 r0) & @brn ~ (p1 r1) @brn = ((@brnS (@brnZ r)) r) @main diff --git a/tests/programs/f24.hvm b/tests/programs/f24.hvm new file mode 100644 index 00000000..2433b5f3 --- /dev/null +++ b/tests/programs/f24.hvm @@ -0,0 +1,41 @@ +@half = xN & 1.0 ~ $([/] $(2.0 xN)) +@nan = xN & 0.0 ~ $([/] $(0.0 xN)) + +@main = x & @t0 ~ (* x) + +// nan and inf divisions +@t0 = (* {n x}) & @t1 ~ (* x) & 1.0 ~ $([/] $(0.0 n)) // +inf +@t1 = (* {n x}) & @t2 ~ (* x) & -1.0 ~ $([/] $(0.0 n)) // -inf +@t2 = (* {n x}) & @t3 ~ (* x) & 0.0 ~ $([/] $(0.0 n)) // NaN + +// general operators +@t3 = (* {n x}) & @t4 ~ (* x) & @half ~ $([+] $(2.0 n)) // 2.5 +@t4 = (* {n x}) & @t5 ~ (* x) & @half ~ $([-] $(2.0 n)) // -1.5 +@t5 = (* {n x}) & @t6 ~ (* x) & @half ~ $([*] $(2.3 n)) // 1.15 +@t6 = (* {n x}) & @t7 ~ (* x) & @half ~ $([/] $(2.0 n)) // 0.25 +@t7 = (* {n x}) & @t8 ~ (* x) & @half ~ $([%] $(2.0 n)) // 0.5 + +// comparisons (returning ints) +@t8 = (* {n x}) & @t9 ~ (* x) & @half ~ $([=] $(2.0 n)) // 0 +@t9 = (* {n x}) & @tA ~ (* x) & @half ~ $([!] $(2.0 n)) // 1 +@tA = (* {n x}) & @tB ~ (* x) & @half ~ $([<] $(2.0 n)) // 1 +@tB = (* {n x}) & @tC ~ (* x) & @half ~ $([>] $(2.0 n)) // 0 + +// ieee nan comparisons +@tC = (* {n x}) & @tD ~ (* x) & @nan ~ $([=] $(@nan n)) // 0 +@tD = (* {n x}) & @tE ~ (* x) & @nan ~ $([<] $(@nan n)) // 0 +@tE = (* {n x}) & @tF ~ (* x) & @nan ~ $([>] $(@nan n)) // 0 + +// parsing +@tF = (* {n x}) & @tG ~ (* x) & +NaN ~ $([+] $(0.0 n)) // NaN +@tG = (* {n x}) & @tH ~ (* x) & +inf ~ $([+] $(0.0 n)) // inf +@tH = (* {n x}) & @tI ~ (* x) & -inf ~ $([+] $(0.0 n)) // -inf +@tI = (* {n x}) & @tJ ~ (* x) & 1.02 ~ $([+] $(0.0 n)) // 1.02 + +// modulo +@tJ = (* {n x}) & @tK ~ (* x) & +1.2 ~ $([%] $(+1.1 n)) // +0.1 +@tK = (* {n x}) & @tL ~ (* x) & +1.2 ~ $([%] $(-1.1 n)) // +0.1 +@tL = (* {n x}) & @tM ~ (* x) & -1.2 ~ $([%] $(+1.1 n)) // -0.1 +@tM = (* {n x}) & @tN ~ (* x) & -1.2 ~ $([%] $(-1.1 n)) // -0.1 + +@tN = * diff --git a/tests/programs/f32.hvm b/tests/programs/f32.hvm deleted file mode 100644 index ed8da372..00000000 --- a/tests/programs/f32.hvm +++ /dev/null @@ -1,36 +0,0 @@ -@half = x & #1.0 ~ -@nan = x & #0.0 ~ - -@main = x - // nan and inf divisions - & x ~ [n x] & #1.0 ~ // inf - & x ~ [n x] & #-1.0 ~ // -inf - & x ~ [n x] & #0.0 ~ // NaN - - // general operators - & x ~ [n x] & @half ~ // 2.5 - & x ~ [n x] & @half ~ // -1.5 - & x ~ [n x] & @half ~ // 1.15 - & x ~ [n x] & @half ~ // 0.25 - & x ~ [n x] & @half ~ // 0.5 - - // comparisons (returning ints) - & x ~ [n x] & @half ~ // 0 - & x ~ [n x] & @half ~ // 1 - & x ~ [n x] & @half ~ // 1 - & x ~ [n x] & @half ~ #2.0 n> // 0 - - // ieee nan comparisons - & x ~ [n x] & @nan ~ // 0 - & x ~ [n x] & @nan ~ // 0 - & x ~ [n x] & @nan ~ // 0 - & x ~ [n x] & @nan ~ = @nan n> // 0 - & x ~ [n x] & @nan ~ @nan n> // 0 - - // parsing - & x ~ [n x] & #NaN ~ // NaN - & x ~ [n x] & #inf ~ // inf - & x ~ [n x] & #-inf ~ // -inf - & x ~ [n x] & #1.02 ~ // 1.02 - - & x ~ * diff --git a/tests/programs/heavy_pre_reduction.hvm b/tests/programs/heavy_pre_reduction.hvm index c0e5624c..cff6620f 100644 --- a/tests/programs/heavy_pre_reduction.hvm +++ b/tests/programs/heavy_pre_reduction.hvm @@ -1,8 +1,8 @@ @C1 = ((a b) (a b)) -@C2 = ({3 (a b) (c a)} (c b)) -@C3 = ({9 (a b) {9 (c a) (d c)}} (d b)) -@C4 = ({7 (a b) {7 (c a) {7 (d c) (e d)}}} (e b)) -@C6 = ({5 (a b) {5 (c a) {5 (d c) {5 (e d) {5 (f e) (g f)}}}}} (g b)) +@C2 = (#1{(a b) (c a)} (c b)) +@C3 = (#4{(a b) #4{(c a) (d c)}} (d b)) +@C4 = (#3{(a b) #3{(c a) #3{(d c) (e d)}}} (e b)) +@C6 = (#2{(a b) #2{(c a) #2{(d c) #2{(e d) #2{(f e) (g f)}}}}} (g b)) @black_plus = a & @black_box ~ (@plus a) @erase = ((@black_box (a b)) (a b)) @@ -15,14 +15,14 @@ @expensive_2 = a & @fib ~ (b a) & @C4 ~ (@C2 b) -@fib = ((@fib$S0 ([@C1 @C1] [* a])) a) -@fib$S0 = ([a {13 b c}] [b d]) +@fib = ((@fib$S0 ({@C1 @C1} {* a})) a) +@fib$S0 = ({a #6{b c}} {b d}) & @plus ~ (a (c d)) @main = * @main_fast = a & @black_plus ~ (@expensive (@expensive a)) @main_slow = a & @black_plus ~ (@expensive_1 (@expensive_2 a)) -@plus = ((a (b c)) ((d (e b)) ({11 a d} (e c)))) +@plus = ((a (b c)) ((d (e b)) (#5{a d} (e c)))) @black_box = (x x) diff --git a/tests/programs/i24.hvm b/tests/programs/i24.hvm new file mode 100644 index 00000000..99b4ea7f --- /dev/null +++ b/tests/programs/i24.hvm @@ -0,0 +1,30 @@ +@main = x & @t0 ~ (* x) + +// all ops +@t0 = (* {n x}) & @t1 ~ (* x) & +10 ~ $([+] $(+2 n)) // 12 +@t1 = (* {n x}) & @t2 ~ (* x) & +10 ~ $([-] $(+2 n)) // 8 +@t2 = (* {n x}) & @t3 ~ (* x) & +10 ~ $([*] $(+2 n)) // 20 +@t3 = (* {n x}) & @t4 ~ (* x) & +10 ~ $([/] $(+2 n)) // 5 +@t4 = (* {n x}) & @t5 ~ (* x) & +10 ~ $([%] $(+2 n)) // 0 +@t5 = (* {n x}) & @t6 ~ (* x) & +10 ~ $([=] $(+2 n)) // 0 +@t6 = (* {n x}) & @t7 ~ (* x) & +10 ~ $([!] $(+2 n)) // 1 +@t7 = (* {n x}) & @t8 ~ (* x) & +10 ~ $([<] $(+2 n)) // 0 +@t8 = (* {n x}) & @t9 ~ (* x) & +10 ~ $([>] $(+2 n)) // 1 +@t9 = (* {n x}) & @tA ~ (* x) & +10 ~ $([&] $(+2 n)) // 2 +@tA = (* {n x}) & @tB ~ (* x) & +10 ~ $([|] $(+2 n)) // 10 +@tB = (* {n x}) & @tC ~ (* x) & +10 ~ $([^] $(+2 n)) // 8 + +// underflow +@tC = (* {n x}) & @tD ~ (* x) & -8388608 ~ $([-] $(+1 n)) // 8388607 + +// overflow +@tD = (* {n x}) & @tE ~ (* x) & +8388607 ~ $([+] $(+1 n)) // -8388608 + +// modulo +@tE = (* {n x}) & @tF ~ (* x) & +3 ~ $([%] $(+2 n)) // +1 +@tF = (* {n x}) & @tG ~ (* x) & +3 ~ $([%] $(-2 n)) // +1 +@tG = (* {n x}) & @tH ~ (* x) & -3 ~ $([%] $(+2 n)) // -1 +@tH = (* {n x}) & @tI ~ (* x) & -3 ~ $([%] $(-2 n)) // -1 + +@tI = * + diff --git a/tests/programs/list_put_got.hvm b/tests/programs/list_put_got.hvm index 6566bb11..ad8f5c45 100644 --- a/tests/programs/list_put_got.hvm +++ b/tests/programs/list_put_got.hvm @@ -5,12 +5,12 @@ & @Put ~ (c (a (b d))) @Got = ((@GotN (@GotC a)) a) @GotC = (a (b ((@GotS (@GotZ (a (b c)))) c))) -@GotN = (* [@None @Nil]) +@GotN = (* {@None @Nil}) @GotS = (a (b (c d))) -& (e [f g]) ~ (b d) +& (e {f g}) ~ (b d) & @Cons ~ (e (h g)) -& @Got ~ (c (a [f h])) -@GotZ = ({3 a b} (c [d e])) +& @Got ~ (c (a {f h})) +@GotZ = (#1{a b} (c {d e})) & @Cons ~ (b (c e)) & @Some ~ (a d) @Nil = (a (* a)) @@ -18,17 +18,17 @@ @Put = ((@PutN (@PutC a)) a) @PutC = (a (b ((@PutCS (@PutCZ (a (b c)))) c))) @PutCS = (a (b (c (d e)))) -& (f [g h]) ~ (b e) +& (f {g h}) ~ (b e) & @Cons ~ (f (i h)) -& @Put ~ (c (a (d [g i]))) -@PutCZ = (a (b (c [d e]))) +& @Put ~ (c (a (d {g i}))) +@PutCZ = (a (b (c {d e}))) & @Cons ~ (c (b e)) & @Some ~ (a d) @PutN = ((@PutNS (@PutNZ a)) a) -@PutNS = (a (b [c d])) +@PutNS = (a (b {c d})) & @Cons ~ (@None (e d)) -& @PutN ~ (a (b [c e])) -@PutNZ = (a [@None b]) +& @PutN ~ (a (b {c e})) +@PutNZ = (a {@None b}) & @Cons ~ (a (@Nil b)) @S0 = (* (a a)) @S1 = ((@S1$S0 a) (* a)) @@ -592,7 +592,7 @@ @S9$S7 = ((@S9$S6 a) (* a)) @S9$S8 = ((@S9$S7 a) (* a)) @Some = (a (* ((a b) b))) -@main = ((a [b *]) b) +@main = ((a {b *}) b) & @Cons ~ (c (d a)) & @Cons ~ (e (f d)) & @Cons ~ (g (h f)) diff --git a/tests/programs/neg_fusion.hvm b/tests/programs/neg_fusion.hvm index 6912b474..9d5b4924 100644 --- a/tests/programs/neg_fusion.hvm +++ b/tests/programs/neg_fusion.hvm @@ -1,4 +1,4 @@ -@C2 = ({3 (a b) (c a)} (c b)) +@C2 = (#1{(a b) (c a)} (c b)) @False = (* (a a)) @Mul = ((a b) ((c a) (c b))) @Neg = ((a (b c)) (b (a c))) diff --git a/tests/programs/numeric_casts.hvm b/tests/programs/numeric_casts.hvm new file mode 100644 index 00000000..16df5e65 --- /dev/null +++ b/tests/programs/numeric_casts.hvm @@ -0,0 +1,45 @@ +@main = x & @tu0 ~ (* x) + +// casting to u24 +@tu0 = (* {n x}) & @tu1 ~ (* x) & 0 ~ $([u24] n) // 0 +@tu1 = (* {n x}) & @tu2 ~ (* x) & 1234 ~ $([u24] n) // 1234 +@tu2 = (* {n x}) & @tu3 ~ (* x) & +4321 ~ $([u24] n) // 4321 +@tu3 = (* {n x}) & @tu4 ~ (* x) & -5678 ~ $([u24] n) // 16771538 (reinterprets bits) +@tu4 = (* {n x}) & @tu5 ~ (* x) & 2.8 ~ $([u24] n) // 2 (rounds to zero) +@tu5 = (* {n x}) & @tu6 ~ (* x) & -12.5 ~ $([u24] n) // 0 (saturates) +@tu6 = (* {n x}) & @tu7 ~ (* x) & 16777216.0 ~ $([u24] n) // 16777215 (saturates) +@tu7 = (* {n x}) & @tu8 ~ (* x) & +inf ~ $([u24] n) // 16777215 (saturates) +@tu8 = (* {n x}) & @tu9 ~ (* x) & -inf ~ $([u24] n) // 0 (saturates) +@tu9 = (* {n x}) & @ti0 ~ (* x) & +NaN ~ $([u24] n) // 0 + +// casting to i24 +@ti0 = (* {n x}) & @ti1 ~ (* x) & 0 ~ $([i24] n) // +0 +@ti1 = (* {n x}) & @ti2 ~ (* x) & 1234 ~ $([i24] n) // +1234 +@ti2 = (* {n x}) & @ti3 ~ (* x) & +4321 ~ $([i24] n) // +4321 +@ti3 = (* {n x}) & @ti4 ~ (* x) & -5678 ~ $([i24] n) // -5678 +@ti4 = (* {n x}) & @ti5 ~ (* x) & 2.8 ~ $([i24] n) // +2 (rounds to zero) +@ti5 = (* {n x}) & @ti6 ~ (* x) & -12.7 ~ $([i24] n) // -12 (rounds to zero) +@ti6 = (* {n x}) & @ti7 ~ (* x) & 8388610.0 ~ $([i24] n) // +8388607 (saturates) +@ti7 = (* {n x}) & @ti8 ~ (* x) & -8388610.0 ~ $([i24] n) // -8388608 (saturates) +@ti8 = (* {n x}) & @ti9 ~ (* x) & +inf ~ $([i24] n) // +8388607 (saturates) +@ti9 = (* {n x}) & @ti10 ~ (* x) & -inf ~ $([i24] n) // -8388608 (saturates) +@ti10 = (* {n x}) & @tf0 ~ (* x) & +NaN ~ $([i24] n) // +0 + +// casting to f24 +@tf0 = (* {n x}) & @tf1 ~ (* x) & +NaN ~ $([f24] n) // +NaN +@tf1 = (* {n x}) & @tf2 ~ (* x) & +inf ~ $([f24] n) // +inf +@tf2 = (* {n x}) & @tf3 ~ (* x) & -inf ~ $([f24] n) // -inf +@tf3 = (* {n x}) & @tf4 ~ (* x) & 2.15 ~ $([f24] n) // 2.15 +@tf4 = (* {n x}) & @tf5 ~ (* x) & -2.15 ~ $([f24] n) // -2.15 +@tf5 = (* {n x}) & @tf6 ~ (* x) & 0.15 ~ $([f24] n) // 0.15 +@tf6 = (* {n x}) & @tf7 ~ (* x) & -1234 ~ $([f24] n) // -1234.0 +@tf7 = (* {n x}) & @tf8 ~ (* x) & +1234 ~ $([f24] n) // +1234.0 +@tf8 = (* {n x}) & @tf9 ~ (* x) & 123456 ~ $([f24] n) // 123456.0 +@tf9 = (* {n x}) & @tp0 ~ (* x) & 16775982 ~ $([f24] n) // 16775936.0 + +// printing +@tp0 = (* {n x}) & @tp1 ~ (* x) & n ~ [u24] // [u24] +@tp1 = (* {n x}) & @tp2 ~ (* x) & n ~ [i24] // [i24] +@tp2 = (* {n x}) & @t ~ (* x) & n ~ [f24] // [f24] + +@t = * diff --git a/tests/programs/nums.hvm b/tests/programs/nums.hvm deleted file mode 100644 index ea83ed1a..00000000 --- a/tests/programs/nums.hvm +++ /dev/null @@ -1,25 +0,0 @@ -// tests numeric parsing and display - -@main = x - // ints - & x ~ [#12345 x] - & x ~ [#0 x] - & x ~ [#-0 x] - & x ~ [#-12345 x] - & x ~ [#0xABC x] - & x ~ [#-0xABC x] - & x ~ [#0b1010 x] - & x ~ [#-0b1010 x] - - // floats - & x ~ [#1.0 x] - & x ~ [#0.1 x] - & x ~ [#0.001 x] - & x ~ [#-123.123 x] - & x ~ [#-12.045e2 x] - & x ~ [#NaN x] - & x ~ [#-NaN x] - & x ~ [#inf x] - & x ~ [#-inf x] - - & x ~ * diff --git a/tests/programs/ops.hvm b/tests/programs/ops.hvm deleted file mode 100644 index fd6e3114..00000000 --- a/tests/programs/ops.hvm +++ /dev/null @@ -1,50 +0,0 @@ -// numbers are printed as `i64`, so over/underflows in `u60` arithmetic might -// change the sign when printed - -@main = x - // underflow - & x ~ [n x] & #0 ~ // 255 - & x ~ [n x] & #0 ~ // 65535 - & x ~ [n x] & #0 ~ // 4294967295 - & x ~ [n x] & #0 ~ // -1 - - // max - & x ~ [n x] & #1 ~ // 255 - & x ~ [n x] & #1 ~ // 65535 - & x ~ [n x] & #1 ~ // 4294967295 - & x ~ [n x] & #1 ~ // -1 - - // overflow - & x ~ [n x] & #1 ~ // 0 - & x ~ [n x] & #1 ~ // 0 - & x ~ [n x] & #1 ~ // 0 - & x ~ [n x] & #1 ~ // 0 - - // sign extension - & x ~ [n x] & #0 ~ // -1 - & x ~ [n x] & #0 ~ // -1 - & x ~ [n x] & #0 ~ // -1 - - // signed overflow - & x ~ [n x] & #2 ~ // -2 - & x ~ [n x] & #2 ~ // -2 - & x ~ [n x] & #2 ~ // -2 - - // all ops - & x ~ [n x] & #10 ~ // 12 - & x ~ [n x] & #10 ~ // 8 - & x ~ [n x] & #10 ~ // 20 - & x ~ [n x] & #10 ~ // 5 - & x ~ [n x] & #10 ~ // 0 - & x ~ [n x] & #10 ~ // 0 - & x ~ [n x] & #10 ~ // 1 - & x ~ [n x] & #10 ~ // 0 - & x ~ [n x] & #10 ~ #2 n> // 1 - & x ~ [n x] & #10 ~ // 2 - & x ~ [n x] & #10 ~ // 10 - & x ~ [n x] & #10 ~ // 8 - & x ~ [n x] & #10 ~ // 40 - & x ~ [n x] & #10 ~ > #2 n> // 2 - & x ~ [n x] & #9 ~ // 0 - - & x ~ * diff --git a/tests/programs/queue.hvm b/tests/programs/queue.hvm index 3a59777f..13043d58 100644 --- a/tests/programs/queue.hvm +++ b/tests/programs/queue.hvm @@ -1,6 +1,6 @@ @C0 = (* (a a)) @C1 = ((a b) (a b)) -@C2 = ({3 (a b) (c a)} (c b)) +@C2 = (#1{(a b) (c a)} (c b)) @Cons = (a (b ((a (b c)) (* c)))) @Nil = (* (a a)) @Queue.add = (a ((((a (b c)) c) d) (b d))) diff --git a/tests/programs/stress_tests/all_tree.hvm b/tests/programs/stress_tests/all_tree.hvm index 1a2aa747..86d7c2fc 100644 --- a/tests/programs/stress_tests/all_tree.hvm +++ b/tests/programs/stress_tests/all_tree.hvm @@ -9,14 +9,14 @@ & @all ~ (a d) @and = (((a a) (@and$S0 b)) b) @and$S0 = (* @False) -@gen = (?<(a b) d> d) +@gen = (?((a b) d) d) & (a b) ~ (c @gen$S0) & @Leaf ~ (@True c) -@gen$S0 = ({3 a b} c) +@gen$S0 = (#1{a b} c) & @Node ~ (d (e c)) & @gen ~ (b e) & @gen ~ (a d) @main = a & @all ~ (b a) -& @gen ~ (#24 b) +& @gen ~ (24 b) diff --git a/tests/programs/stress_tests/apelacion.hvm b/tests/programs/stress_tests/apelacion.hvm index c6d242fb..bd693061 100644 --- a/tests/programs/stress_tests/apelacion.hvm +++ b/tests/programs/stress_tests/apelacion.hvm @@ -1,13 +1,13 @@ @main = a -& @rec ~ (#6 a) -@rec = (?<(a b) d> d) +& @rec ~ (6 a) +@rec = (?((a b) d) d) & (a b) ~ (c @rec$S0) -& @sum ~ (#1000000 (#0 c)) -@rec$S0 = ({5 a b} c) -& @rec ~ (a <+ d c>) +& @sum ~ (1000000 (0 c)) +@rec$S0 = (#2{a b} c) +& @rec ~ (a $([+] $(d c))) & @rec ~ (b d) -@sum = (?<(a b) d> d) +@sum = (?((a b) d) d) & (a b) ~ ((c c) @sum$S0) -@sum$S0 = ({3 a <+ b c>} (b d)) +@sum$S0 = (#1{a $([+] $(b c))} (b d)) & @sum ~ (a (c d)) diff --git a/tests/programs/stress_tests/boom.hvm b/tests/programs/stress_tests/boom.hvm index 95fd5db0..c4ecfa71 100644 --- a/tests/programs/stress_tests/boom.hvm +++ b/tests/programs/stress_tests/boom.hvm @@ -1,31 +1,31 @@ // Exponentiation of Church encodings. -@c2 = ({1 {1 (c b) (b a)} (a R)} (c R)) -@c4 = ({1 {1 {1 (d c) (c b)} (b a)} (a R)} (d R)) -@c6 = ({1 {1 {1 {1 {1 (f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) -@c8 = ({1 {1 {1 {1 {1 {1 {1 (h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) -@c11 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 (j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) -@c12 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) -@c14 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) -@c16 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) -@c21 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) -@c22 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) -@c24 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c2 = ({{(c b) (b a)} (a R)} (c R)) +@c4 = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c6 = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c8 = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c11 = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c12 = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c14 = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c16 = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c21 = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c22 = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c24 = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) -@k3 = ({2 {2 (c b) (b a)} (a R)} (c R)) -@k4 = ({2 {2 {2 (d c) (c b)} (b a)} (a R)} (d R)) -@k6 = ({2 {2 {2 {2 {2 (f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) -@k8 = ({2 {2 {2 {2 {2 {2 {2 (h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) -@k20 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 (j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) -@k22 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) -@k24 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) -@k26 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) -@k20 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) -@k22 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) -@k24 = ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 (x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@k3 = (#1(#1((c b) (b a)) (a R)) (c R)) +@k4 = (#1(#1(#1((d c) (c b)) (b a)) (a R)) (d R)) +@k6 = (#1(#1(#1(#1(#1((f e) (e d)) (d c)) (c b)) (b a)) (a R)) (f R)) +@k8 = (#1(#1(#1(#1(#1(#1(#1((h g) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (h R)) +@k20 = (#1(#1(#1(#1(#1(#1(#1(#1(#1((j i) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (j R)) +@k22 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((l k) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (l R)) +@k24 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((n m) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (n R)) +@k26 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((p o) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (p R)) +@k20 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((t s) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (t R)) +@k22 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((v u) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (v R)) +@k24 = (#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((x w) (w v)) (v u)) (u t)) (t s)) (s r)) (r q)) (q p)) (p o)) (o n)) (n m)) (m l)) (l k)) (k j)) (j i)) (i h)) (h g)) (g f)) (f e)) (e d)) (d c)) (c b)) (b a)) (a R)) (x R)) -@A = ({1 (a b) (b c)} (a c)) -@B = ({2 (a b) (b c)} (a c)) +@A = ({(a b) (b c)} (a c)) +@B = (#1((a b) (b c)) (a c)) @F = (* (x x)) @N = ((@F (@T a)) a) @T = (a (* a)) diff --git a/tests/programs/stress_tests/burn.hvm b/tests/programs/stress_tests/burn.hvm index 8e46ab11..f3169863 100644 --- a/tests/programs/stress_tests/burn.hvm +++ b/tests/programs/stress_tests/burn.hvm @@ -1,17 +1,17 @@ // Decreases a tree of λ-encoded binary counters until they're all 0 (parallel). // Takes about ~16s on Apple M1, and ~0.5s on RTX 4090 -@c3 = ({1 {1 (c b) (b a)} (a R)} (c R)) -@c4 = ({1 {1 {1 (d c) (c b)} (b a)} (a R)} (d R)) -@c6 = ({1 {1 {1 {1 {1 (f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) -@c8 = ({1 {1 {1 {1 {1 {1 {1 (h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) -@c10 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 (j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) -@c12 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) -@c14 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) -@c16 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) -@c20 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) -@c22 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) -@c24 = ({1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 {1 (x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) +@c3 = ({{(c b) (b a)} (a R)} (c R)) +@c4 = ({{{(d c) (c b)} (b a)} (a R)} (d R)) +@c6 = ({{{{{(f e) (e d)} (d c)} (c b)} (b a)} (a R)} (f R)) +@c8 = ({{{{{{{(h g) (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (h R)) +@c10 = ({{{{{{{{{(j i) (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (j R)) +@c12 = ({{{{{{{{{{{(l k) (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (l R)) +@c14 = ({{{{{{{{{{{{{(n m) (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (n R)) +@c16 = ({{{{{{{{{{{{{{{(p o) (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (p R)) +@c20 = ({{{{{{{{{{{{{{{{{{{(t s) (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (t R)) +@c22 = ({{{{{{{{{{{{{{{{{{{{{(v u) (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (v R)) +@c24 = ({{{{{{{{{{{{{{{{{{{{{{{(x w) (w v)} (v u)} (u t)} (t s)} (s r)} (r q)} (q p)} (p o)} (o n)} (n m)} (m l)} (l k)} (k j)} (j i)} (i h)} (h g)} (g f)} (f e)} (e d)} (d c)} (c b)} (b a)} (a R)} (x R)) @S = (a ((a b) (* b))) @Z = (* (a a)) @@ -33,7 +33,7 @@ @run = ((@runO (@runI (@E R))) R) @brnZ = (* R) & @run ~ (val R) & @c20 ~ (@I (@E val)) -@brnS = ({1 p0 p1} (r0 r1)) & @brn ~ (p0 r0) & @brn ~ (p1 r1) +@brnS = ({p0 p1} (r0 r1)) & @brn ~ (p0 r0) & @brn ~ (p1 r1) @brn = ((@brnS (@brnZ r)) r) @main diff --git a/tests/programs/stress_tests/fib_rec.hvm b/tests/programs/stress_tests/fib_rec.hvm index f3d8e058..c3e08086 100644 --- a/tests/programs/stress_tests/fib_rec.hvm +++ b/tests/programs/stress_tests/fib_rec.hvm @@ -1,12 +1,12 @@ -@add = (<+ a b> (a b)) -@fib = (?<(a b) c> c) -& (a b) ~ (#1 @fib$S2) -@fib$S0 = (* #1) +@add = ($([+] $(a b)) (a b)) +@fib = (?((a b) c) c) +& (a b) ~ (1 @fib$S2) +@fib$S0 = (* 1) @fib$S1 = (a (b c)) -& @fib ~ (b <+ d c>) +& @fib ~ (b $([+] $(d c))) & @fib ~ (a d) -@fib$S2 = ({3 ?<(a b) (c d)> c} d) +@fib$S2 = (#1{?((a b) (c d)) c} d) & (a b) ~ (@fib$S0 @fib$S1) @main = a -& @fib ~ (#30 a) +& @fib ~ (30 a) diff --git a/tests/programs/stress_tests/sum_rec.bend b/tests/programs/stress_tests/sum_rec.bend index d094f909..fd6a08f3 100644 --- a/tests/programs/stress_tests/sum_rec.bend +++ b/tests/programs/stress_tests/sum_rec.bend @@ -5,4 +5,4 @@ sum = λn match n { 1+: (add (sum n-1) (sum n-1)) } -main = (sum 26) +main = (sum 23) diff --git a/tests/programs/stress_tests/sum_rec.hvm b/tests/programs/stress_tests/sum_rec.hvm index 960b33ae..2f735353 100644 --- a/tests/programs/stress_tests/sum_rec.hvm +++ b/tests/programs/stress_tests/sum_rec.hvm @@ -1,9 +1,9 @@ -@add = (<+ a b> (a b)) +@add = ($([+] $(a b)) (a b)) @main = a -& @sum ~ (#26 a) -@sum = (?<(a b) c> c) -& (a b) ~ (#1 @sum$S0) -@sum$S0 = ({3 a b} c) +& @sum ~ (23 a) +@sum = (?((a b) c) c) +& (a b) ~ (1 @sum$S0) +@sum$S0 = (#1{a b} c) & @add ~ (d (e c)) & @sum ~ (b e) & @sum ~ (a d) diff --git a/tests/programs/stress_tests/sum_tail.hvm b/tests/programs/stress_tests/sum_tail.hvm index d87e3e59..ec19f9d7 100644 --- a/tests/programs/stress_tests/sum_tail.hvm +++ b/tests/programs/stress_tests/sum_tail.hvm @@ -1,7 +1,7 @@ @main = a -& @sum ~ (#10000000 (#0 a)) -@sum = (?<(a b) d> d) +& @sum ~ (10000000 (0 a)) +@sum = (?((a b) d) d) & (a b) ~ ((c c) @sum$S0) -@sum$S0 = ({3 a <+ b c>} (b d)) +@sum$S0 = (#1{a $([+] $(b c))} (b d)) & @sum ~ (a (c d)) diff --git a/tests/programs/stress_tests/sum_tree.hvm b/tests/programs/stress_tests/sum_tree.hvm index 2efcd423..19a8c330 100644 --- a/tests/programs/stress_tests/sum_tree.hvm +++ b/tests/programs/stress_tests/sum_tree.hvm @@ -1,16 +1,16 @@ @Leaf = (a ((a b) (* b))) @Node = (a (b (* ((a (b c)) c)))) -@add = (<+ a b> (a b)) -@gen = (?<(a b) d> d) +@add = ($([+] $(a b)) (a b)) +@gen = (?((a b) d) d) & (a b) ~ (c @gen$S0) -& @Leaf ~ (#1 c) -@gen$S0 = ({3 a b} c) +& @Leaf ~ (1 c) +@gen$S0 = (#1{a b} c) & @Node ~ (d (e c)) & @gen ~ (b e) & @gen ~ (a d) @main = a & @sum ~ (b a) -& @gen ~ (#24 b) +& @gen ~ (24 b) @sum = (((a a) (@sum$S0 b)) b) @sum$S0 = (a (b c)) & @add ~ (d (e c)) diff --git a/tests/programs/stress_tests/tuple_rots.hvm b/tests/programs/stress_tests/tuple_rots.hvm index 38226b5c..2506d0f3 100644 --- a/tests/programs/stress_tests/tuple_rots.hvm +++ b/tests/programs/stress_tests/tuple_rots.hvm @@ -1,12 +1,12 @@ @MkTup8 = (a (b (c (d (e (f (g (h ((a (b (c (d (e (f (g (h i)))))))) i))))))))) -@app = (?<(a b) c> c) +@app = (?((a b) c) c) & (a b) ~ (@app$S0 @app$S1) @app$S0 = (* (a a)) -@app$S1 = (a ({3 b (c d)} (c e))) +@app$S1 = (a (#1{b (c d)} (c e))) & @app ~ (a (b (d e))) @main = a -& @app ~ (#2000000 (@rot (b a))) -& @MkTup8 ~ (#1 (#2 (#3 (#4 (#5 (#6 (#7 (#8 b)))))))) +& @app ~ (2000000 (@rot (b a))) +& @MkTup8 ~ (1 (2 (3 (4 (5 (6 (7 (8 b)))))))) @rot = ((@rot$S0 a) a) @rot$S0 = (a (b (c (d (e (f (g (h i)))))))) & @MkTup8 ~ (b (c (d (e (f (g (h (a i)))))))) diff --git a/tests/programs/u24.hvm b/tests/programs/u24.hvm new file mode 100644 index 00000000..a5e17b60 --- /dev/null +++ b/tests/programs/u24.hvm @@ -0,0 +1,28 @@ +@main = x & @t0 ~ (* x) + +// all ops +@t0 = (* {n x}) & @t1 ~ (* x) & 10 ~ $([+] $(2 n)) // 12 +@t1 = (* {n x}) & @t2 ~ (* x) & 10 ~ $([-] $(2 n)) // 8 +@t2 = (* {n x}) & @t3 ~ (* x) & 10 ~ $([*] $(2 n)) // 20 +@t3 = (* {n x}) & @t4 ~ (* x) & 10 ~ $([/] $(2 n)) // 5 +@t4 = (* {n x}) & @t5 ~ (* x) & 10 ~ $([%] $(2 n)) // 0 +@t5 = (* {n x}) & @t6 ~ (* x) & 10 ~ $([=] $(2 n)) // 0 +@t6 = (* {n x}) & @t7 ~ (* x) & 10 ~ $([!] $(2 n)) // 1 +@t7 = (* {n x}) & @t8 ~ (* x) & 10 ~ $([<] $(2 n)) // 0 +@t8 = (* {n x}) & @t9 ~ (* x) & 10 ~ $([>] $(2 n)) // 1 +@t9 = (* {n x}) & @tA ~ (* x) & 10 ~ $([&] $(2 n)) // 2 +@tA = (* {n x}) & @tB ~ (* x) & 10 ~ $([|] $(2 n)) // 10 +@tB = (* {n x}) & @tC ~ (* x) & 10 ~ $([^] $(2 n)) // 8 +@tC = (* {n x}) & @tD ~ (* x) & 10 ~ $([<<] $(2 n)) // 40 +@tD = (* {n x}) & @tE ~ (* x) & 10 ~ $([>>] $(2 n)) // 2 + +// underflow +@tE = (* {n x}) & @tF ~ (* x) & 0 ~ $([-] $(1 n)) // 16777215 + +// overflow +@tF = (* {n x}) & @tG ~ (* x) & 16777215 ~ $([+] $(1 n)) // 0 + +// no sign extension +@tG = (* {n x}) & @tH ~ (* x) & 16777215 ~ $([>>] $(22 n)) // 3 + +@tH = * diff --git a/tests/programs/very_large.hvm b/tests/programs/very_large.hvm index 49178c52..96590767 100644 --- a/tests/programs/very_large.hvm +++ b/tests/programs/very_large.hvm @@ -1 +1 @@ -@main = (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (*(* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* *)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) \ No newline at end of file +@main = (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* (* *)))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))) \ No newline at end of file diff --git a/tests/snapshots/pre_reduce_run@examples::arithmetic.snap b/tests/snapshots/pre_reduce_run@examples::arithmetic.snap index d4009f33..62bf9faa 100644 --- a/tests/snapshots/pre_reduce_run@examples::arithmetic.snap +++ b/tests/snapshots/pre_reduce_run@examples::arithmetic.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/arithmetic.hvm --- -({3 <% c d>} ({5 a c} [b d])) +(#1{$([/] $(a b)) $([%] $(c d))} (#2{a c} {b d})) pre-reduce: RWTS : 5 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@examples::church_encoding::church.snap b/tests/snapshots/pre_reduce_run@examples::church_encoding::church.snap index 4c2d83bf..19e5ff6c 100644 --- a/tests/snapshots/pre_reduce_run@examples::church_encoding::church.snap +++ b/tests/snapshots/pre_reduce_run@examples::church_encoding::church.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/church_encoding/church.hvm --- -({9 {7 (a {5 b c}) {7 (d a) ({5 c e} d)}} {3 (f e) {3 (g f) {3 (h g) {3 (i h) *}}}}} (i b)) +(#4{#3{(a #2{b c}) #3{(d a) (#2{c e} d)}} #1{(f e) #1{(g f) #1{(h g) #1{(i h) *}}}}} (i b)) pre-reduce: RWTS : 24 - ANNI : 12 diff --git a/tests/snapshots/pre_reduce_run@examples::machine_u32::num_add.snap b/tests/snapshots/pre_reduce_run@examples::machine_u32::num_add.snap index 81d0b45b..7ed523be 100644 --- a/tests/snapshots/pre_reduce_run@examples::machine_u32::num_add.snap +++ b/tests/snapshots/pre_reduce_run@examples::machine_u32::num_add.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/machine_u32/num_add.hvm --- -#223 +223 pre-reduce: RWTS : 1 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@examples::machine_u32::num_match.snap b/tests/snapshots/pre_reduce_run@examples::machine_u32::num_match.snap index bc1442b6..6e4fcfa4 100644 --- a/tests/snapshots/pre_reduce_run@examples::machine_u32::num_match.snap +++ b/tests/snapshots/pre_reduce_run@examples::machine_u32::num_match.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/machine_u32/num_match.hvm --- -#9 +9 pre-reduce: RWTS : 2 - ANNI : 1 diff --git a/tests/snapshots/pre_reduce_run@examples::sort::bitonic::bitonic_sort_lam.snap b/tests/snapshots/pre_reduce_run@examples::sort::bitonic::bitonic_sort_lam.snap index 6de9c683..48fcd75c 100644 --- a/tests/snapshots/pre_reduce_run@examples::sort::bitonic::bitonic_sort_lam.snap +++ b/tests/snapshots/pre_reduce_run@examples::sort::bitonic::bitonic_sort_lam.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/bitonic/bitonic_sort_lam.hvm --- -#523776 +523776 pre-reduce: RWTS : 130 - ANNI : 51 diff --git a/tests/snapshots/pre_reduce_run@examples::sort::merge::merge_sort.snap b/tests/snapshots/pre_reduce_run@examples::sort::merge::merge_sort.snap index a35c01ff..854c4b19 100644 --- a/tests/snapshots/pre_reduce_run@examples::sort::merge::merge_sort.snap +++ b/tests/snapshots/pre_reduce_run@examples::sort::merge::merge_sort.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/merge/merge_sort.hvm --- -{4 * {4 {4 {4 * {4 {4 {4 {4 #3 a} {4 * a}} {4 {4 {4 #2 b} {4 * b}} c}} c}} {4 {4 * {4 {4 {4 {4 #1 d} {4 * d}} {4 {4 {4 #0 e} {4 * e}} f}} f}} g}} g}} +#2(* #2(#2(#2(* #2(#2(#2(#2(3 a) #2(* a)) #2(#2(#2(2 b) #2(* b)) c)) c)) #2(#2(* #2(#2(#2(#2(1 d) #2(* d)) #2(#2(#2(0 e) #2(* e)) f)) f)) g)) g)) pre-reduce: RWTS : 53 - ANNI : 21 diff --git a/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_ctr.snap b/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_ctr.snap index ac16a11f..7d77777c 100644 --- a/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_ctr.snap +++ b/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_ctr.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/radix/radix_sort_ctr.hvm --- -#549755289600 +16252928 pre-reduce: RWTS : 150 - ANNI : 63 diff --git a/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_lam.snap b/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_lam.snap index 1fd6c906..aaf818bf 100644 --- a/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_lam.snap +++ b/tests/snapshots/pre_reduce_run@examples::sort::radix::radix_sort_lam.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/radix/radix_sort_lam.hvm --- -#549755289600 +16252928 pre-reduce: RWTS : 153 - ANNI : 63 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::chained_ops.snap b/tests/snapshots/pre_reduce_run@tests::programs::chained_ops.snap index 1de31dc5..f983ad9c 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::chained_ops.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::chained_ops.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/chained_ops.hvm --- -#7184190578800 +2138224 pre-reduce: RWTS : 0 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::church_exp.snap b/tests/snapshots/pre_reduce_run@tests::programs::church_exp.snap index ce48735d..66f9054e 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::church_exp.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::church_exp.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/church_exp.hvm --- -({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 a b} c} d} e} f} g} h} i} j} k} l} m} n} o} p} q} r} s} t} u} v} w} x} y} z} aa} ab} ac} ad} ae} af} ag} ah} ai} aj} ak} al} am} an} ao} ap} aq} ar} as} at} au} av} aw} ax} ay} az} ba} bb} bc} bd} be} bf} bg} bh} bi} bj} bk} bl} bm} bn} bo} bp} bq} br} bs} bt} bu} bv} bw} bx} by} bz} ca} cb} cc} cd} ce} cf} cg} ch} ci} cj} ck} cl} cm} cn} co} cp} cq} cr} cs} ct} cu} cv} cw} cx} cy} cz} da} db} dc} dd} de} df} dg} dh} di} dj} dk} dl} dm} dn} do} dp} dq} dr} ds} dt} du} dv} dw} dx} dy} dz} ea} eb} ec} ed} ee} ef} eg} eh} ei} ej} ek} el} em} en} eo} ep} eq} er} es} et} eu} ev} ew} ex} ey} ez} fa} fb} fc} fd} fe} ff} fg} fh} fi} fj} fk} fl} fm} fn} fo} fp} fq} fr} fs} ft} fu} fv} fw} fx} fy} fz} ga} gb} gc} gd} ge} gf} gg} gh} gi} gj} gk} gl} gm} gn} go} gp} gq} gr} gs} gt} gu} gv} gw} gx} gy} gz} ha} hb} hc} hd} he} hf} hg} hh} hi} hj} hk} hl} hm} hn} ho} hp} hq} hr} hs} ht} hu} hv} hw} hx} hy} hz} ia} ib} ic} id} ie} if} ig} ih} ii} ij} ik} il} im} in} io} ip} iq} ir} is} it} iu} iv} iw} ix} iy} iz} ja} jb} jc} jd} je} jf} jg} jh} ji} jj} jk} jl} jm} jn} jo} jp} jq} jr} js} jt} ju} jv} jw} jx} jy} jz} ka} kb} kc} kd} ke} kf} kg} kh} ki} kj} kk} kl} km} kn} ko} kp} kq} kr} ks} kt} ku} kv} kw} kx} ky} kz} la} lb} lc} ld} le} lf} lg} lh} li} lj} lk} ll} lm} ln} lo} lp} lq} lr} ls} lt} lu} lv} lw} lx} ly} lz} ma} mb} mc} md} me} mf} mg} mh} mi} mj} mk} ml} mm} mn} mo} mp} mq} mr} ms} mt} mu} mv} mw} mx} my) (my mz)} (mz na)} (na nb)} (nb nc)} (nc nd)} (nd ne)} (ne nf)} (nf ng)} (ng nh)} (nh ni)} (ni nj)} (nj nk)} (nk nl)} (nl nm)} (nm nn)} (nn no)} (no np)} (np nq)} (nq {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 mf mg} mh} mi} mj} mk} ml} mm} mn} mo} mp} mq} mr} ms} mt} mu} mv} mw} mx} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 lm ln} lo} lp} lq} lr} ls} lt} lu} lv} lw} lx} ly} lz} ma} mb} mc} md} me} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 kt ku} kv} kw} kx} ky} kz} la} lb} lc} ld} le} lf} lg} lh} li} lj} lk} ll} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ka kb} kc} kd} ke} kf} kg} kh} ki} kj} kk} kl} km} kn} ko} kp} kq} kr} ks} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 jh ji} jj} jk} jl} jm} jn} jo} jp} jq} jr} js} jt} ju} jv} jw} jx} jy} jz} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 io ip} iq} ir} is} it} iu} iv} iw} ix} iy} iz} ja} jb} jc} jd} je} jf} jg} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 hv hw} hx} hy} hz} ia} ib} ic} id} ie} if} ig} ih} ii} ij} ik} il} im} in} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 hc hd} he} hf} hg} hh} hi} hj} hk} hl} hm} hn} ho} hp} hq} hr} hs} ht} hu} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 gj gk} gl} gm} gn} go} gp} gq} gr} gs} gt} gu} gv} gw} gx} gy} gz} ha} hb} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 fq fr} fs} ft} fu} fv} fw} fx} fy} fz} ga} gb} gc} gd} ge} gf} gg} gh} gi} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ex ey} ez} fa} fb} fc} fd} fe} ff} fg} fh} fi} fj} fk} fl} fm} fn} fo} fp} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ee ef} eg} eh} ei} ej} ek} el} em} en} eo} ep} eq} er} es} et} eu} ev} ew} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 dl dm} dn} do} dp} dq} dr} ds} dt} du} dv} dw} dx} dy} dz} ea} eb} ec} ed} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 cs ct} cu} cv} cw} cx} cy} cz} da} db} dc} dd} de} df} dg} dh} di} dj} dk} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 bz ca} cb} cc} cd} ce} cf} cg} ch} ci} cj} ck} cl} cm} cn} co} cp} cq} cr} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 bg bh} bi} bj} bk} bl} bm} bn} bo} bp} bq} br} bs} bt} bu} bv} bw} bx} by} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 an ao} ap} aq} ar} as} at} au} av} aw} ax} ay} az} ba} bb} bc} bd} be} bf} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 u v} w} x} y} z} aa} ab} ac} ad} ae} af} ag} ah} ai} aj} ak} al} am} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 b c} d} e} f} g} h} i} j} k} l} m} n} o} p} q} r} s} t} nr}}}}}}}}}}}}}}}}}}})} (a nr)) +(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(a b) c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) s) t) u) v) w) x) y) z) aa) ab) ac) ad) ae) af) ag) ah) ai) aj) ak) al) am) an) ao) ap) aq) ar) as) at) au) av) aw) ax) ay) az) ba) bb) bc) bd) be) bf) bg) bh) bi) bj) bk) bl) bm) bn) bo) bp) bq) br) bs) bt) bu) bv) bw) bx) by) bz) ca) cb) cc) cd) ce) cf) cg) ch) ci) cj) ck) cl) cm) cn) co) cp) cq) cr) cs) ct) cu) cv) cw) cx) cy) cz) da) db) dc) dd) de) df) dg) dh) di) dj) dk) dl) dm) dn) do) dp) dq) dr) ds) dt) du) dv) dw) dx) dy) dz) ea) eb) ec) ed) ee) ef) eg) eh) ei) ej) ek) el) em) en) eo) ep) eq) er) es) et) eu) ev) ew) ex) ey) ez) fa) fb) fc) fd) fe) ff) fg) fh) fi) fj) fk) fl) fm) fn) fo) fp) fq) fr) fs) ft) fu) fv) fw) fx) fy) fz) ga) gb) gc) gd) ge) gf) gg) gh) gi) gj) gk) gl) gm) gn) go) gp) gq) gr) gs) gt) gu) gv) gw) gx) gy) gz) ha) hb) hc) hd) he) hf) hg) hh) hi) hj) hk) hl) hm) hn) ho) hp) hq) hr) hs) ht) hu) hv) hw) hx) hy) hz) ia) ib) ic) id) ie) if) ig) ih) ii) ij) ik) il) im) in) io) ip) iq) ir) is) it) iu) iv) iw) ix) iy) iz) ja) jb) jc) jd) je) jf) jg) jh) ji) jj) jk) jl) jm) jn) jo) jp) jq) jr) js) jt) ju) jv) jw) jx) jy) jz) ka) kb) kc) kd) ke) kf) kg) kh) ki) kj) kk) kl) km) kn) ko) kp) kq) kr) ks) kt) ku) kv) kw) kx) ky) kz) la) lb) lc) ld) le) lf) lg) lh) li) lj) lk) ll) lm) ln) lo) lp) lq) lr) ls) lt) lu) lv) lw) lx) ly) lz) ma) mb) mc) md) me) mf) mg) mh) mi) mj) mk) ml) mm) mn) mo) mp) mq) mr) ms) mt) mu) mv) mw) mx) my) (my mz)) (mz na)) (na nb)) (nb nc)) (nc nd)) (nd ne)) (ne nf)) (nf ng)) (ng nh)) (nh ni)) (ni nj)) (nj nk)) (nk nl)) (nl nm)) (nm nn)) (nn no)) (no np)) (np nq)) (nq #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(mf mg) mh) mi) mj) mk) ml) mm) mn) mo) mp) mq) mr) ms) mt) mu) mv) mw) mx) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(lm ln) lo) lp) lq) lr) ls) lt) lu) lv) lw) lx) ly) lz) ma) mb) mc) md) me) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(kt ku) kv) kw) kx) ky) kz) la) lb) lc) ld) le) lf) lg) lh) li) lj) lk) ll) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ka kb) kc) kd) ke) kf) kg) kh) ki) kj) kk) kl) km) kn) ko) kp) kq) kr) ks) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(jh ji) jj) jk) jl) jm) jn) jo) jp) jq) jr) js) jt) ju) jv) jw) jx) jy) jz) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(io ip) iq) ir) is) it) iu) iv) iw) ix) iy) iz) ja) jb) jc) jd) je) jf) jg) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(hv hw) hx) hy) hz) ia) ib) ic) id) ie) if) ig) ih) ii) ij) ik) il) im) in) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(hc hd) he) hf) hg) hh) hi) hj) hk) hl) hm) hn) ho) hp) hq) hr) hs) ht) hu) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(gj gk) gl) gm) gn) go) gp) gq) gr) gs) gt) gu) gv) gw) gx) gy) gz) ha) hb) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(fq fr) fs) ft) fu) fv) fw) fx) fy) fz) ga) gb) gc) gd) ge) gf) gg) gh) gi) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ex ey) ez) fa) fb) fc) fd) fe) ff) fg) fh) fi) fj) fk) fl) fm) fn) fo) fp) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ee ef) eg) eh) ei) ej) ek) el) em) en) eo) ep) eq) er) es) et) eu) ev) ew) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(dl dm) dn) do) dp) dq) dr) ds) dt) du) dv) dw) dx) dy) dz) ea) eb) ec) ed) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(cs ct) cu) cv) cw) cx) cy) cz) da) db) dc) dd) de) df) dg) dh) di) dj) dk) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(bz ca) cb) cc) cd) ce) cf) cg) ch) ci) cj) ck) cl) cm) cn) co) cp) cq) cr) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(bg bh) bi) bj) bk) bl) bm) bn) bo) bp) bq) br) bs) bt) bu) bv) bw) bx) by) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(an ao) ap) aq) ar) as) at) au) av) aw) ax) ay) az) ba) bb) bc) bd) be) bf) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(u v) w) x) y) z) aa) ab) ac) ad) ae) af) ag) ah) ai) aj) ak) al) am) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(b c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) s) t) nr))))))))))))))))))))) (a nr)) pre-reduce: RWTS : 54 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::church_mul.snap b/tests/snapshots/pre_reduce_run@tests::programs::church_mul.snap index 4d54541d..a8a1be35 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::church_mul.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::church_mul.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/church_mul.hvm --- -({3 (a {3 b {3 c {3 d {3 e {3 f {3 g {3 h {3 i {3 j {3 k {3 l {3 m {3 n {3 o {3 p {3 q {3 r {3 s {3 t u}}}}}}}}}}}}}}}}}}}) {3 (v a) {3 (w v) {3 (x w) {3 (y x) {3 (z y) {3 (aa z) {3 (ab aa) {3 (ac ab) {3 (ad ac) {3 (ae ad) {3 (af ae) {3 (ag af) {3 (ah ag) {3 (ai ah) {3 (aj ai) {3 (ak aj) {3 (al ak) {3 (am al) ({3 c {3 d {3 e {3 f {3 g {3 h {3 i {3 j {3 k {3 l {3 m {3 n {3 o {3 p {3 q {3 r {3 s {3 t {3 u an}}}}}}}}}}}}}}}}}}} am)}}}}}}}}}}}}}}}}}}} (an b)) +(#1{(a #1{b #1{c #1{d #1{e #1{f #1{g #1{h #1{i #1{j #1{k #1{l #1{m #1{n #1{o #1{p #1{q #1{r #1{s #1{t u}}}}}}}}}}}}}}}}}}}) #1{(v a) #1{(w v) #1{(x w) #1{(y x) #1{(z y) #1{(aa z) #1{(ab aa) #1{(ac ab) #1{(ad ac) #1{(ae ad) #1{(af ae) #1{(ag af) #1{(ah ag) #1{(ai ah) #1{(aj ai) #1{(ak aj) #1{(al ak) #1{(am al) (#1{c #1{d #1{e #1{f #1{g #1{h #1{i #1{j #1{k #1{l #1{m #1{n #1{o #1{p #1{q #1{r #1{s #1{t #1{u an}}}}}}}}}}}}}}}}}}} am)}}}}}}}}}}}}}}}}}}} (an b)) pre-reduce: RWTS : 2 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::f24.snap b/tests/snapshots/pre_reduce_run@tests::programs::f24.snap new file mode 100644 index 00000000..803fb8f6 --- /dev/null +++ b/tests/snapshots/pre_reduce_run@tests::programs::f24.snap @@ -0,0 +1,20 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/f24.hvm +--- +{+inf {-inf {+NaN {2.5 {-1.5 {1.1499939 {0.25 {0.5 {0 {1 {1 {0 {0 {0 {0 {+NaN {+inf {-inf {1.019989 {0.1000061 {0.1000061 {-0.1000061 {-0.1000061 *}}}}}}}}}}}}}}}}}}}}}}} +pre-reduce: +RWTS : 134 +- ANNI : 22 +- COMM : 1 +- ERAS : 23 +- DREF : 63 +- OPER : 25 +run: +RWTS : 53 +- ANNI : 1 +- COMM : 0 +- ERAS : 1 +- DREF : 51 +- OPER : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::f32.snap b/tests/snapshots/pre_reduce_run@tests::programs::f32.snap deleted file mode 100644 index 958adf30..00000000 --- a/tests/snapshots/pre_reduce_run@tests::programs::f32.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/f32.hvm ---- -[#inf [#-inf [#NaN [#2.5 [#-1.5 [#1.15 [#0.25 [#0.5 [#0 [#1 [#1 [#0 [#0 [#0 [#0 [#0 [#0 [#NaN [#inf [#-inf [#1.02 *]]]]]]]]]]]]]]]]]]]]] -pre-reduce: -RWTS : 4 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 2 -- OPER : 2 -run: -RWTS : 84 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 63 -- OPER : 21 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::i24.snap b/tests/snapshots/pre_reduce_run@tests::programs::i24.snap new file mode 100644 index 00000000..ab3107c4 --- /dev/null +++ b/tests/snapshots/pre_reduce_run@tests::programs::i24.snap @@ -0,0 +1,20 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/i24.hvm +--- +{+12 {+8 {+20 {+5 {+0 {0 {1 {0 {1 {+2 {+10 {+8 {+8388607 {-8388608 {+1 {+1 {-1 {-1 *}}}}}}}}}}}}}}}}}} +pre-reduce: +RWTS : 90 +- ANNI : 17 +- COMM : 1 +- ERAS : 18 +- DREF : 36 +- OPER : 18 +run: +RWTS : 43 +- ANNI : 1 +- COMM : 0 +- ERAS : 1 +- DREF : 41 +- OPER : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::list_put_got.snap b/tests/snapshots/pre_reduce_run@tests::programs::list_put_got.snap index d208469e..dc4d801e 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::list_put_got.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::list_put_got.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/list_put_got.hvm --- -(((* (((* (((* (a a)) b) b)) ((* (((* (((((* (c c)) d) (* d)) e) e)) ((* (((* (((((((* (f f)) g) (* g)) h) (* h)) i) i)) ((* (((* (((((((((* (j j)) k) (* k)) l) (* l)) m) (* m)) n) n)) ((* (((* (((((((((((* (o o)) p) (* p)) q) (* q)) r) (* r)) s) (* s)) t) t)) ((* (((* (((((((((((((* (u u)) v) (* v)) w) (* w)) x) (* x)) y) (* y)) z) (* z)) aa) aa)) ((* (((* (((((((((((((((* (ab ab)) ac) (* ac)) ad) (* ad)) ae) (* ae)) af) (* af)) ag) (* ag)) ah) (* ah)) ai) ai)) ((* (((* (((((((((((((((((* (aj aj)) ak) (* ak)) al) (* al)) am) (* am)) an) (* an)) ao) (* ao)) ap) (* ap)) aq) (* aq)) ar) ar)) ((* (((* (((((((((((((((((((* (as as)) at) (* at)) au) (* au)) av) (* av)) aw) (* aw)) ax) (* ax)) ay) (* ay)) az) (* az)) ba) (* ba)) bb) bb)) ((* (((* (((((((((((((((((((((* (bc bc)) bd) (* bd)) be) (* be)) bf) (* bf)) bg) (* bg)) bh) (* bh)) bi) (* bi)) bj) (* bj)) bk) (* bk)) bl) (* bl)) bm) bm)) ((* (((* (((((((((((((((((((((((* (bn bn)) bo) (* bo)) bp) (* bp)) bq) (* bq)) br) (* br)) bs) (* bs)) bt) (* bt)) bu) (* bu)) bv) (* bv)) bw) (* bw)) bx) (* bx)) by) by)) ((* (((* (((((((((((((((((((((((((* (bz bz)) ca) (* ca)) cb) (* cb)) cc) (* cc)) cd) (* cd)) ce) (* ce)) cf) (* cf)) cg) (* cg)) ch) (* ch)) ci) (* ci)) cj) (* cj)) ck) (* ck)) cl) cl)) ((* (((* (((((((((((((((((((((((((((* (cm cm)) cn) (* cn)) co) (* co)) cp) (* cp)) cq) (* cq)) cr) (* cr)) cs) (* cs)) ct) (* ct)) cu) (* cu)) cv) (* cv)) cw) (* cw)) cx) (* cx)) cy) (* cy)) cz) cz)) ((* (((* (((((((((((((((((((((((((((((* (da da)) db) (* db)) dc) (* dc)) dd) (* dd)) de) (* de)) df) (* df)) dg) (* dg)) dh) (* dh)) di) (* di)) dj) (* dj)) dk) (* dk)) dl) (* dl)) dm) (* dm)) dn) (* dn)) do) do)) ((* (((* (((((((((((((((((((((((((((((((* (dp dp)) dq) (* dq)) dr) (* dr)) ds) (* ds)) dt) (* dt)) du) (* du)) dv) (* dv)) dw) (* dw)) dx) (* dx)) dy) (* dy)) dz) (* dz)) ea) (* ea)) eb) (* eb)) ec) (* ec)) ed) (* ed)) ee) ee)) ((* (((* (((((((((((((((((((((((((((((((((* (ef ef)) eg) (* eg)) eh) (* eh)) ei) (* ei)) ej) (* ej)) ek) (* ek)) el) (* el)) em) (* em)) en) (* en)) eo) (* eo)) ep) (* ep)) eq) (* eq)) er) (* er)) es) (* es)) et) (* et)) eu) (* eu)) ev) ev)) ((* (((* (((((((((((((((((((((((((((((((((((* (ew ew)) ex) (* ex)) ey) (* ey)) ez) (* ez)) fa) (* fa)) fb) (* fb)) fc) (* fc)) fd) (* fd)) fe) (* fe)) ff) (* ff)) fg) (* fg)) fh) (* fh)) fi) (* fi)) fj) (* fj)) fk) (* fk)) fl) (* fl)) fm) (* fm)) fn) fn)) ((* (((* (((((((((((((((((((((((((((((((((((((* (fo fo)) fp) (* fp)) fq) (* fq)) fr) (* fr)) fs) (* fs)) ft) (* ft)) fu) (* fu)) fv) (* fv)) fw) (* fw)) fx) (* fx)) fy) (* fy)) fz) (* fz)) ga) (* ga)) gb) (* gb)) gc) (* gc)) gd) (* gd)) ge) (* ge)) gf) (* gf)) gg) gg)) ((* (((* (((((((((((((((((((((((((((((((((((((((* (gh gh)) gi) (* gi)) gj) (* gj)) gk) (* gk)) gl) (* gl)) gm) (* gm)) gn) (* gn)) go) (* go)) gp) (* gp)) gq) (* gq)) gr) (* gr)) gs) (* gs)) gt) (* gt)) gu) (* gu)) gv) (* gv)) gw) (* gw)) gx) (* gx)) gy) (* gy)) gz) (* gz)) ha) ha)) ((* (((* (((((((((((((((((((((((((((((((((((((((((* (hb hb)) hc) (* hc)) hd) (* hd)) he) (* he)) hf) (* hf)) hg) (* hg)) hh) (* hh)) hi) (* hi)) hj) (* hj)) hk) (* hk)) hl) (* hl)) hm) (* hm)) hn) (* hn)) ho) (* ho)) hp) (* hp)) hq) (* hq)) hr) (* hr)) hs) (* hs)) ht) (* ht)) hu) (* hu)) hv) hv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((* (hw hw)) hx) (* hx)) hy) (* hy)) hz) (* hz)) ia) (* ia)) ib) (* ib)) ic) (* ic)) id) (* id)) ie) (* ie)) if) (* if)) ig) (* ig)) ih) (* ih)) ii) (* ii)) ij) (* ij)) ik) (* ik)) il) (* il)) im) (* im)) in) (* in)) io) (* io)) ip) (* ip)) iq) (* iq)) ir) ir)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((* (is is)) it) (* it)) iu) (* iu)) iv) (* iv)) iw) (* iw)) ix) (* ix)) iy) (* iy)) iz) (* iz)) ja) (* ja)) jb) (* jb)) jc) (* jc)) jd) (* jd)) je) (* je)) jf) (* jf)) jg) (* jg)) jh) (* jh)) ji) (* ji)) jj) (* jj)) jk) (* jk)) jl) (* jl)) jm) (* jm)) jn) (* jn)) jo) jo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((* (jp jp)) jq) (* jq)) jr) (* jr)) js) (* js)) jt) (* jt)) ju) (* ju)) jv) (* jv)) jw) (* jw)) jx) (* jx)) jy) (* jy)) jz) (* jz)) ka) (* ka)) kb) (* kb)) kc) (* kc)) kd) (* kd)) ke) (* ke)) kf) (* kf)) kg) (* kg)) kh) (* kh)) ki) (* ki)) kj) (* kj)) kk) (* kk)) kl) (* kl)) km) km)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((* (kn kn)) ko) (* ko)) kp) (* kp)) kq) (* kq)) kr) (* kr)) ks) (* ks)) kt) (* kt)) ku) (* ku)) kv) (* kv)) kw) (* kw)) kx) (* kx)) ky) (* ky)) kz) (* kz)) la) (* la)) lb) (* lb)) lc) (* lc)) ld) (* ld)) le) (* le)) lf) (* lf)) lg) (* lg)) lh) (* lh)) li) (* li)) lj) (* lj)) lk) (* lk)) ll) ll)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((* (lm lm)) ln) (* ln)) lo) (* lo)) lp) (* lp)) lq) (* lq)) lr) (* lr)) ls) (* ls)) lt) (* lt)) lu) (* lu)) lv) (* lv)) lw) (* lw)) lx) (* lx)) ly) (* ly)) lz) (* lz)) ma) (* ma)) mb) (* mb)) mc) (* mc)) md) (* md)) me) (* me)) mf) (* mf)) mg) (* mg)) mh) (* mh)) mi) (* mi)) mj) (* mj)) mk) (* mk)) ml) ml)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((* (mm mm)) mn) (* mn)) mo) (* mo)) mp) (* mp)) mq) (* mq)) mr) (* mr)) ms) (* ms)) mt) (* mt)) mu) (* mu)) mv) (* mv)) mw) (* mw)) mx) (* mx)) my) (* my)) mz) (* mz)) na) (* na)) nb) (* nb)) nc) (* nc)) nd) (* nd)) ne) (* ne)) nf) (* nf)) ng) (* ng)) nh) (* nh)) ni) (* ni)) nj) (* nj)) nk) (* nk)) nl) (* nl)) nm) nm)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((* (nn nn)) no) (* no)) np) (* np)) nq) (* nq)) nr) (* nr)) ns) (* ns)) nt) (* nt)) nu) (* nu)) nv) (* nv)) nw) (* nw)) nx) (* nx)) ny) (* ny)) nz) (* nz)) oa) (* oa)) ob) (* ob)) oc) (* oc)) od) (* od)) oe) (* oe)) of) (* of)) og) (* og)) oh) (* oh)) oi) (* oi)) oj) (* oj)) ok) (* ok)) ol) (* ol)) om) (* om)) on) (* on)) oo) oo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (op op)) oq) (* oq)) or) (* or)) os) (* os)) ot) (* ot)) ou) (* ou)) ov) (* ov)) ow) (* ow)) ox) (* ox)) oy) (* oy)) oz) (* oz)) pa) (* pa)) pb) (* pb)) pc) (* pc)) pd) (* pd)) pe) (* pe)) pf) (* pf)) pg) (* pg)) ph) (* ph)) pi) (* pi)) pj) (* pj)) pk) (* pk)) pl) (* pl)) pm) (* pm)) pn) (* pn)) po) (* po)) pp) (* pp)) pq) (* pq)) pr) pr)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (ps ps)) pt) (* pt)) pu) (* pu)) pv) (* pv)) pw) (* pw)) px) (* px)) py) (* py)) pz) (* pz)) qa) (* qa)) qb) (* qb)) qc) (* qc)) qd) (* qd)) qe) (* qe)) qf) (* qf)) qg) (* qg)) qh) (* qh)) qi) (* qi)) qj) (* qj)) qk) (* qk)) ql) (* ql)) qm) (* qm)) qn) (* qn)) qo) (* qo)) qp) (* qp)) qq) (* qq)) qr) (* qr)) qs) (* qs)) qt) (* qt)) qu) (* qu)) qv) qv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (qw qw)) qx) (* qx)) qy) (* qy)) qz) (* qz)) ra) (* ra)) rb) (* rb)) rc) (* rc)) rd) (* rd)) re) (* re)) rf) (* rf)) rg) (* rg)) rh) (* rh)) ri) (* ri)) rj) (* rj)) rk) (* rk)) rl) (* rl)) rm) (* rm)) rn) (* rn)) ro) (* ro)) rp) (* rp)) rq) (* rq)) rr) (* rr)) rs) (* rs)) rt) (* rt)) ru) (* ru)) rv) (* rv)) rw) (* rw)) rx) (* rx)) ry) (* ry)) rz) (* rz)) sa) sa)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (sb sb)) sc) (* sc)) sd) (* sd)) se) (* se)) sf) (* sf)) sg) (* sg)) sh) (* sh)) si) (* si)) sj) (* sj)) sk) (* sk)) sl) (* sl)) sm) (* sm)) sn) (* sn)) so) (* so)) sp) (* sp)) sq) (* sq)) sr) (* sr)) ss) (* ss)) st) (* st)) su) (* su)) sv) (* sv)) sw) (* sw)) sx) (* sx)) sy) (* sy)) sz) (* sz)) ta) (* ta)) tb) (* tb)) tc) (* tc)) td) (* td)) te) (* te)) tf) (* tf)) tg) tg)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (th th)) ti) (* ti)) tj) (* tj)) tk) (* tk)) tl) (* tl)) tm) (* tm)) tn) (* tn)) to) (* to)) tp) (* tp)) tq) (* tq)) tr) (* tr)) ts) (* ts)) tt) (* tt)) tu) (* tu)) tv) (* tv)) tw) (* tw)) tx) (* tx)) ty) (* ty)) tz) (* tz)) ua) (* ua)) ub) (* ub)) uc) (* uc)) ud) (* ud)) ue) (* ue)) uf) (* uf)) ug) (* ug)) uh) (* uh)) ui) (* ui)) uj) (* uj)) uk) (* uk)) ul) (* ul)) um) (* um)) un) un)) ((uo (* uo)) up)) up)) uq)) uq)) ur)) ur)) us)) us)) ut)) ut)) uu)) uu)) uv)) uv)) uw)) uw)) ux)) ux)) uy)) uy)) uz)) uz)) va)) va)) vb)) vb)) vc)) vc)) vd)) vd)) ve)) ve)) vf)) vf)) vg)) vg)) vh)) vh)) vi)) vi)) vj)) vj)) vk)) vk)) vl)) vl)) vm)) vm)) vn)) vn)) vo)) vo)) vp)) vp)) vq)) vq)) vr)) vr)) vs)) vs)) vt)) vt)) vu)) vu)) [vv *]) vv) +(((* (((* (((* (a a)) b) b)) ((* (((* (((((* (c c)) d) (* d)) e) e)) ((* (((* (((((((* (f f)) g) (* g)) h) (* h)) i) i)) ((* (((* (((((((((* (j j)) k) (* k)) l) (* l)) m) (* m)) n) n)) ((* (((* (((((((((((* (o o)) p) (* p)) q) (* q)) r) (* r)) s) (* s)) t) t)) ((* (((* (((((((((((((* (u u)) v) (* v)) w) (* w)) x) (* x)) y) (* y)) z) (* z)) aa) aa)) ((* (((* (((((((((((((((* (ab ab)) ac) (* ac)) ad) (* ad)) ae) (* ae)) af) (* af)) ag) (* ag)) ah) (* ah)) ai) ai)) ((* (((* (((((((((((((((((* (aj aj)) ak) (* ak)) al) (* al)) am) (* am)) an) (* an)) ao) (* ao)) ap) (* ap)) aq) (* aq)) ar) ar)) ((* (((* (((((((((((((((((((* (as as)) at) (* at)) au) (* au)) av) (* av)) aw) (* aw)) ax) (* ax)) ay) (* ay)) az) (* az)) ba) (* ba)) bb) bb)) ((* (((* (((((((((((((((((((((* (bc bc)) bd) (* bd)) be) (* be)) bf) (* bf)) bg) (* bg)) bh) (* bh)) bi) (* bi)) bj) (* bj)) bk) (* bk)) bl) (* bl)) bm) bm)) ((* (((* (((((((((((((((((((((((* (bn bn)) bo) (* bo)) bp) (* bp)) bq) (* bq)) br) (* br)) bs) (* bs)) bt) (* bt)) bu) (* bu)) bv) (* bv)) bw) (* bw)) bx) (* bx)) by) by)) ((* (((* (((((((((((((((((((((((((* (bz bz)) ca) (* ca)) cb) (* cb)) cc) (* cc)) cd) (* cd)) ce) (* ce)) cf) (* cf)) cg) (* cg)) ch) (* ch)) ci) (* ci)) cj) (* cj)) ck) (* ck)) cl) cl)) ((* (((* (((((((((((((((((((((((((((* (cm cm)) cn) (* cn)) co) (* co)) cp) (* cp)) cq) (* cq)) cr) (* cr)) cs) (* cs)) ct) (* ct)) cu) (* cu)) cv) (* cv)) cw) (* cw)) cx) (* cx)) cy) (* cy)) cz) cz)) ((* (((* (((((((((((((((((((((((((((((* (da da)) db) (* db)) dc) (* dc)) dd) (* dd)) de) (* de)) df) (* df)) dg) (* dg)) dh) (* dh)) di) (* di)) dj) (* dj)) dk) (* dk)) dl) (* dl)) dm) (* dm)) dn) (* dn)) do) do)) ((* (((* (((((((((((((((((((((((((((((((* (dp dp)) dq) (* dq)) dr) (* dr)) ds) (* ds)) dt) (* dt)) du) (* du)) dv) (* dv)) dw) (* dw)) dx) (* dx)) dy) (* dy)) dz) (* dz)) ea) (* ea)) eb) (* eb)) ec) (* ec)) ed) (* ed)) ee) ee)) ((* (((* (((((((((((((((((((((((((((((((((* (ef ef)) eg) (* eg)) eh) (* eh)) ei) (* ei)) ej) (* ej)) ek) (* ek)) el) (* el)) em) (* em)) en) (* en)) eo) (* eo)) ep) (* ep)) eq) (* eq)) er) (* er)) es) (* es)) et) (* et)) eu) (* eu)) ev) ev)) ((* (((* (((((((((((((((((((((((((((((((((((* (ew ew)) ex) (* ex)) ey) (* ey)) ez) (* ez)) fa) (* fa)) fb) (* fb)) fc) (* fc)) fd) (* fd)) fe) (* fe)) ff) (* ff)) fg) (* fg)) fh) (* fh)) fi) (* fi)) fj) (* fj)) fk) (* fk)) fl) (* fl)) fm) (* fm)) fn) fn)) ((* (((* (((((((((((((((((((((((((((((((((((((* (fo fo)) fp) (* fp)) fq) (* fq)) fr) (* fr)) fs) (* fs)) ft) (* ft)) fu) (* fu)) fv) (* fv)) fw) (* fw)) fx) (* fx)) fy) (* fy)) fz) (* fz)) ga) (* ga)) gb) (* gb)) gc) (* gc)) gd) (* gd)) ge) (* ge)) gf) (* gf)) gg) gg)) ((* (((* (((((((((((((((((((((((((((((((((((((((* (gh gh)) gi) (* gi)) gj) (* gj)) gk) (* gk)) gl) (* gl)) gm) (* gm)) gn) (* gn)) go) (* go)) gp) (* gp)) gq) (* gq)) gr) (* gr)) gs) (* gs)) gt) (* gt)) gu) (* gu)) gv) (* gv)) gw) (* gw)) gx) (* gx)) gy) (* gy)) gz) (* gz)) ha) ha)) ((* (((* (((((((((((((((((((((((((((((((((((((((((* (hb hb)) hc) (* hc)) hd) (* hd)) he) (* he)) hf) (* hf)) hg) (* hg)) hh) (* hh)) hi) (* hi)) hj) (* hj)) hk) (* hk)) hl) (* hl)) hm) (* hm)) hn) (* hn)) ho) (* ho)) hp) (* hp)) hq) (* hq)) hr) (* hr)) hs) (* hs)) ht) (* ht)) hu) (* hu)) hv) hv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((* (hw hw)) hx) (* hx)) hy) (* hy)) hz) (* hz)) ia) (* ia)) ib) (* ib)) ic) (* ic)) id) (* id)) ie) (* ie)) if) (* if)) ig) (* ig)) ih) (* ih)) ii) (* ii)) ij) (* ij)) ik) (* ik)) il) (* il)) im) (* im)) in) (* in)) io) (* io)) ip) (* ip)) iq) (* iq)) ir) ir)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((* (is is)) it) (* it)) iu) (* iu)) iv) (* iv)) iw) (* iw)) ix) (* ix)) iy) (* iy)) iz) (* iz)) ja) (* ja)) jb) (* jb)) jc) (* jc)) jd) (* jd)) je) (* je)) jf) (* jf)) jg) (* jg)) jh) (* jh)) ji) (* ji)) jj) (* jj)) jk) (* jk)) jl) (* jl)) jm) (* jm)) jn) (* jn)) jo) jo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((* (jp jp)) jq) (* jq)) jr) (* jr)) js) (* js)) jt) (* jt)) ju) (* ju)) jv) (* jv)) jw) (* jw)) jx) (* jx)) jy) (* jy)) jz) (* jz)) ka) (* ka)) kb) (* kb)) kc) (* kc)) kd) (* kd)) ke) (* ke)) kf) (* kf)) kg) (* kg)) kh) (* kh)) ki) (* ki)) kj) (* kj)) kk) (* kk)) kl) (* kl)) km) km)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((* (kn kn)) ko) (* ko)) kp) (* kp)) kq) (* kq)) kr) (* kr)) ks) (* ks)) kt) (* kt)) ku) (* ku)) kv) (* kv)) kw) (* kw)) kx) (* kx)) ky) (* ky)) kz) (* kz)) la) (* la)) lb) (* lb)) lc) (* lc)) ld) (* ld)) le) (* le)) lf) (* lf)) lg) (* lg)) lh) (* lh)) li) (* li)) lj) (* lj)) lk) (* lk)) ll) ll)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((* (lm lm)) ln) (* ln)) lo) (* lo)) lp) (* lp)) lq) (* lq)) lr) (* lr)) ls) (* ls)) lt) (* lt)) lu) (* lu)) lv) (* lv)) lw) (* lw)) lx) (* lx)) ly) (* ly)) lz) (* lz)) ma) (* ma)) mb) (* mb)) mc) (* mc)) md) (* md)) me) (* me)) mf) (* mf)) mg) (* mg)) mh) (* mh)) mi) (* mi)) mj) (* mj)) mk) (* mk)) ml) ml)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((* (mm mm)) mn) (* mn)) mo) (* mo)) mp) (* mp)) mq) (* mq)) mr) (* mr)) ms) (* ms)) mt) (* mt)) mu) (* mu)) mv) (* mv)) mw) (* mw)) mx) (* mx)) my) (* my)) mz) (* mz)) na) (* na)) nb) (* nb)) nc) (* nc)) nd) (* nd)) ne) (* ne)) nf) (* nf)) ng) (* ng)) nh) (* nh)) ni) (* ni)) nj) (* nj)) nk) (* nk)) nl) (* nl)) nm) nm)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((* (nn nn)) no) (* no)) np) (* np)) nq) (* nq)) nr) (* nr)) ns) (* ns)) nt) (* nt)) nu) (* nu)) nv) (* nv)) nw) (* nw)) nx) (* nx)) ny) (* ny)) nz) (* nz)) oa) (* oa)) ob) (* ob)) oc) (* oc)) od) (* od)) oe) (* oe)) of) (* of)) og) (* og)) oh) (* oh)) oi) (* oi)) oj) (* oj)) ok) (* ok)) ol) (* ol)) om) (* om)) on) (* on)) oo) oo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (op op)) oq) (* oq)) or) (* or)) os) (* os)) ot) (* ot)) ou) (* ou)) ov) (* ov)) ow) (* ow)) ox) (* ox)) oy) (* oy)) oz) (* oz)) pa) (* pa)) pb) (* pb)) pc) (* pc)) pd) (* pd)) pe) (* pe)) pf) (* pf)) pg) (* pg)) ph) (* ph)) pi) (* pi)) pj) (* pj)) pk) (* pk)) pl) (* pl)) pm) (* pm)) pn) (* pn)) po) (* po)) pp) (* pp)) pq) (* pq)) pr) pr)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (ps ps)) pt) (* pt)) pu) (* pu)) pv) (* pv)) pw) (* pw)) px) (* px)) py) (* py)) pz) (* pz)) qa) (* qa)) qb) (* qb)) qc) (* qc)) qd) (* qd)) qe) (* qe)) qf) (* qf)) qg) (* qg)) qh) (* qh)) qi) (* qi)) qj) (* qj)) qk) (* qk)) ql) (* ql)) qm) (* qm)) qn) (* qn)) qo) (* qo)) qp) (* qp)) qq) (* qq)) qr) (* qr)) qs) (* qs)) qt) (* qt)) qu) (* qu)) qv) qv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (qw qw)) qx) (* qx)) qy) (* qy)) qz) (* qz)) ra) (* ra)) rb) (* rb)) rc) (* rc)) rd) (* rd)) re) (* re)) rf) (* rf)) rg) (* rg)) rh) (* rh)) ri) (* ri)) rj) (* rj)) rk) (* rk)) rl) (* rl)) rm) (* rm)) rn) (* rn)) ro) (* ro)) rp) (* rp)) rq) (* rq)) rr) (* rr)) rs) (* rs)) rt) (* rt)) ru) (* ru)) rv) (* rv)) rw) (* rw)) rx) (* rx)) ry) (* ry)) rz) (* rz)) sa) sa)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (sb sb)) sc) (* sc)) sd) (* sd)) se) (* se)) sf) (* sf)) sg) (* sg)) sh) (* sh)) si) (* si)) sj) (* sj)) sk) (* sk)) sl) (* sl)) sm) (* sm)) sn) (* sn)) so) (* so)) sp) (* sp)) sq) (* sq)) sr) (* sr)) ss) (* ss)) st) (* st)) su) (* su)) sv) (* sv)) sw) (* sw)) sx) (* sx)) sy) (* sy)) sz) (* sz)) ta) (* ta)) tb) (* tb)) tc) (* tc)) td) (* td)) te) (* te)) tf) (* tf)) tg) tg)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (th th)) ti) (* ti)) tj) (* tj)) tk) (* tk)) tl) (* tl)) tm) (* tm)) tn) (* tn)) to) (* to)) tp) (* tp)) tq) (* tq)) tr) (* tr)) ts) (* ts)) tt) (* tt)) tu) (* tu)) tv) (* tv)) tw) (* tw)) tx) (* tx)) ty) (* ty)) tz) (* tz)) ua) (* ua)) ub) (* ub)) uc) (* uc)) ud) (* ud)) ue) (* ue)) uf) (* uf)) ug) (* ug)) uh) (* uh)) ui) (* ui)) uj) (* uj)) uk) (* uk)) ul) (* ul)) um) (* um)) un) un)) ((uo (* uo)) up)) up)) uq)) uq)) ur)) ur)) us)) us)) ut)) ut)) uu)) uu)) uv)) uv)) uw)) uw)) ux)) ux)) uy)) uy)) uz)) uz)) va)) va)) vb)) vb)) vc)) vc)) vd)) vd)) ve)) ve)) vf)) vf)) vg)) vg)) vh)) vh)) vi)) vi)) vj)) vj)) vk)) vk)) vl)) vl)) vm)) vm)) vn)) vn)) vo)) vo)) vp)) vp)) vq)) vq)) vr)) vr)) vs)) vs)) vt)) vt)) vu)) vu)) {vv *}) vv) pre-reduce: RWTS : 613 - ANNI : 21 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::numeric_casts.snap b/tests/snapshots/pre_reduce_run@tests::programs::numeric_casts.snap new file mode 100644 index 00000000..c1ea5582 --- /dev/null +++ b/tests/snapshots/pre_reduce_run@tests::programs::numeric_casts.snap @@ -0,0 +1,20 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/numeric_casts.hvm +--- +{0 {1234 {4321 {16771538 {2 {0 {16777215 {16777215 {0 {0 {+0 {+1234 {+4321 {-5678 {+2 {-12 {+8388607 {-8388608 {+8388607 {-8388608 {+0 {+NaN {+inf {-inf {2.1500244 {-2.1500244 {0.15000153 {-1234.0 {1234.0 {123456.0 {16775936.0 {[u24] {[i24] {[f24] *}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +pre-reduce: +RWTS : 167 +- ANNI : 33 +- COMM : 1 +- ERAS : 34 +- DREF : 68 +- OPER : 31 +run: +RWTS : 75 +- ANNI : 1 +- COMM : 0 +- ERAS : 1 +- DREF : 73 +- OPER : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::nums.snap b/tests/snapshots/pre_reduce_run@tests::programs::nums.snap deleted file mode 100644 index a641e70f..00000000 --- a/tests/snapshots/pre_reduce_run@tests::programs::nums.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/nums.hvm ---- -[#12345 [#0 [#0 [#-12345 [#2748 [#-2748 [#10 [#-10 [#1.0 [#0.1 [#0.001 [#-123.123 [#-1204.5 [#NaN [#NaN [#inf [#-inf *]]]]]]]]]]]]]]]]] -pre-reduce: -RWTS : 0 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 0 -- OPER : 0 -run: -RWTS : 36 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 36 -- OPER : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::ops.snap b/tests/snapshots/pre_reduce_run@tests::programs::ops.snap deleted file mode 100644 index a6d33c2c..00000000 --- a/tests/snapshots/pre_reduce_run@tests::programs::ops.snap +++ /dev/null @@ -1,20 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/ops.hvm ---- -[#255 [#65535 [#4294967295 [#-1 [#255 [#65535 [#4294967295 [#-1 [#0 [#0 [#0 [#0 [#-1 [#-1 [#-1 [#-2 [#-2 [#-2 [#12 [#8 [#20 [#5 [#0 [#0 [#1 [#0 [#1 [#2 [#10 [#8 [#40 [#2 [#0 *]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] -pre-reduce: -RWTS : 0 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 0 -- OPER : 0 -run: -RWTS : 101 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 68 -- OPER : 33 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::queue.snap b/tests/snapshots/pre_reduce_run@tests::programs::queue.snap index 066a258c..86238b2f 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::queue.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::queue.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/queue.hvm --- -(((* (a a)) (((((b c) (b c)) (((({3 (d e) (f d)} (f e)) ((* (g g)) h)) (* h)) i)) (* i)) j)) (* j)) +(((* (a a)) (((((b c) (b c)) ((((#1{(d e) (f d)} (f e)) ((* (g g)) h)) (* h)) i)) (* i)) j)) (* j)) pre-reduce: RWTS : 8 - ANNI : 0 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::apelacion.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::apelacion.snap index 6c1330d8..794edefc 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::apelacion.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::apelacion.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/apelacion.hvm --- -#31999968000000 +12171264 pre-reduce: RWTS : 33_000_035 - ANNI : 13_000_019 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::fib_rec.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::fib_rec.snap index cba8c09c..83656705 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::fib_rec.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::fib_rec.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/fib_rec.hvm --- -#1346269 +1346269 pre-reduce: RWTS : 13 - ANNI : 6 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_rec.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_rec.snap index cf477bc4..b42317cb 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_rec.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_rec.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_rec.hvm --- -#67108864 +8388608 pre-reduce: RWTS : 13 - ANNI : 7 @@ -12,9 +12,9 @@ RWTS : 13 - DREF : 6 - OPER : 0 run: -RWTS : 671_088_637 -- ANNI : 201_326_591 -- COMM : 67_108_863 -- ERAS : 134_217_727 -- DREF : 67_108_866 -- OPER : 201_326_590 +RWTS : 83_886_077 +- ANNI : 25_165_823 +- COMM : 8_388_607 +- ERAS : 16_777_215 +- DREF : 8_388_610 +- OPER : 25_165_822 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tail.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tail.snap index 23203670..7c1f1f12 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tail.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tail.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_tail.hvm --- -#49999995000000 +15783104 pre-reduce: RWTS : 6 - ANNI : 3 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tree.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tree.snap index 004f47ba..0b813d0a 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tree.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::sum_tree.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_tree.hvm --- -#16777216 +0 pre-reduce: RWTS : 30 - ANNI : 14 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::tuple_rots.snap b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::tuple_rots.snap index 6ea1315d..7a5bcabe 100644 --- a/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::tuple_rots.snap +++ b/tests/snapshots/pre_reduce_run@tests::programs::stress_tests::tuple_rots.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/tuple_rots.hvm --- -((#1 (#2 (#3 (#4 (#5 (#6 (#7 (#8 a)))))))) a) +((1 (2 (3 (4 (5 (6 (7 (8 a)))))))) a) pre-reduce: RWTS : 19 - ANNI : 11 diff --git a/tests/snapshots/pre_reduce_run@tests::programs::u24.snap b/tests/snapshots/pre_reduce_run@tests::programs::u24.snap new file mode 100644 index 00000000..9d74a8d8 --- /dev/null +++ b/tests/snapshots/pre_reduce_run@tests::programs::u24.snap @@ -0,0 +1,20 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/u24.hvm +--- +{12 {8 {20 {5 {0 {0 {1 {0 {1 {2 {10 {8 {40 {2 {16777215 {0 {3 *}}}}}}}}}}}}}}}}} +pre-reduce: +RWTS : 85 +- ANNI : 16 +- COMM : 1 +- ERAS : 17 +- DREF : 34 +- OPER : 17 +run: +RWTS : 41 +- ANNI : 1 +- COMM : 0 +- ERAS : 1 +- DREF : 39 +- OPER : 0 diff --git a/tests/snapshots/run@examples::arithmetic.snap b/tests/snapshots/run@examples::arithmetic.snap index 7263cf1c..276885f3 100644 --- a/tests/snapshots/run@examples::arithmetic.snap +++ b/tests/snapshots/run@examples::arithmetic.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/arithmetic.hvm --- -({3 <% c d>} ({5 a c} [b d])) +(#1{$([/] $(a b)) $([%] $(c d))} (#2{a c} {b d})) RWTS : 18 - ANNI : 4 - COMM : 0 diff --git a/tests/snapshots/run@examples::church_encoding::church.snap b/tests/snapshots/run@examples::church_encoding::church.snap index 57f746a4..161f78a3 100644 --- a/tests/snapshots/run@examples::church_encoding::church.snap +++ b/tests/snapshots/run@examples::church_encoding::church.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/church_encoding/church.hvm --- -({9 {7 (a {5 b c}) {7 (d a) ({5 c e} d)}} {3 (f e) {3 (g f) {3 (h g) {3 (i h) *}}}}} (i b)) +(#4{#3{(a #2{b c}) #3{(d a) (#2{c e} d)}} #1{(f e) #1{(g f) #1{(h g) #1{(i h) *}}}}} (i b)) RWTS : 65 - ANNI : 25 - COMM : 1 diff --git a/tests/snapshots/run@examples::machine_u32::num_add.snap b/tests/snapshots/run@examples::machine_u32::num_add.snap index 3391ff47..3ef01378 100644 --- a/tests/snapshots/run@examples::machine_u32::num_add.snap +++ b/tests/snapshots/run@examples::machine_u32::num_add.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/machine_u32/num_add.hvm --- -#223 +223 RWTS : 6 - ANNI : 2 - COMM : 0 diff --git a/tests/snapshots/run@examples::machine_u32::num_match.snap b/tests/snapshots/run@examples::machine_u32::num_match.snap index d6b4801b..3e2aafc2 100644 --- a/tests/snapshots/run@examples::machine_u32::num_match.snap +++ b/tests/snapshots/run@examples::machine_u32::num_match.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/machine_u32/num_match.hvm --- -#9 +9 RWTS : 9 - ANNI : 4 - COMM : 0 diff --git a/tests/snapshots/run@examples::sort::bitonic::bitonic_sort_lam.snap b/tests/snapshots/run@examples::sort::bitonic::bitonic_sort_lam.snap index ce342688..78afc5dd 100644 --- a/tests/snapshots/run@examples::sort::bitonic::bitonic_sort_lam.snap +++ b/tests/snapshots/run@examples::sort::bitonic::bitonic_sort_lam.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/bitonic/bitonic_sort_lam.hvm --- -#523776 +523776 RWTS : 2_293_690 - ANNI : 1_375_188 - COMM : 96_766 diff --git a/tests/snapshots/run@examples::sort::merge::merge_sort.snap b/tests/snapshots/run@examples::sort::merge::merge_sort.snap index 8f02e748..073cceba 100644 --- a/tests/snapshots/run@examples::sort::merge::merge_sort.snap +++ b/tests/snapshots/run@examples::sort::merge::merge_sort.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/merge/merge_sort.hvm --- -{4 * {4 {4 {4 * {4 {4 {4 {4 #3 a} {4 * a}} {4 {4 {4 #2 b} {4 * b}} c}} c}} {4 {4 * {4 {4 {4 {4 #1 d} {4 * d}} {4 {4 {4 #0 e} {4 * e}} f}} f}} g}} g}} +#2(* #2(#2(#2(* #2(#2(#2(#2(3 a) #2(* a)) #2(#2(#2(2 b) #2(* b)) c)) c)) #2(#2(* #2(#2(#2(#2(1 d) #2(* d)) #2(#2(#2(0 e) #2(* e)) f)) f)) g)) g)) RWTS : 474 - ANNI : 71 - COMM : 242 diff --git a/tests/snapshots/run@examples::sort::radix::radix_sort_ctr.snap b/tests/snapshots/run@examples::sort::radix::radix_sort_ctr.snap index ee5bf776..a05af66c 100644 --- a/tests/snapshots/run@examples::sort::radix::radix_sort_ctr.snap +++ b/tests/snapshots/run@examples::sort::radix::radix_sort_ctr.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/radix/radix_sort_ctr.hvm --- -#549755289600 +16252928 RWTS : 1_376_780_298 - ANNI : 795_869_169 - COMM : 53_477_380 diff --git a/tests/snapshots/run@examples::sort::radix::radix_sort_lam.snap b/tests/snapshots/run@examples::sort::radix::radix_sort_lam.snap index ff19f824..232291e8 100644 --- a/tests/snapshots/run@examples::sort::radix::radix_sort_lam.snap +++ b/tests/snapshots/run@examples::sort::radix::radix_sort_lam.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: examples/sort/radix/radix_sort_lam.hvm --- -#549755289600 +16252928 RWTS : 1_500_512_246 - ANNI : 846_200_803 - COMM : 28_311_560 diff --git a/tests/snapshots/run@tests::programs::chained_ops.snap b/tests/snapshots/run@tests::programs::chained_ops.snap index cf5616d6..1d65819a 100644 --- a/tests/snapshots/run@tests::programs::chained_ops.snap +++ b/tests/snapshots/run@tests::programs::chained_ops.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/chained_ops.hvm --- -#7184190578800 +2138224 RWTS : 28 - ANNI : 2 - COMM : 4 diff --git a/tests/snapshots/run@tests::programs::church_exp.snap b/tests/snapshots/run@tests::programs::church_exp.snap index 58171205..66dc92a3 100644 --- a/tests/snapshots/run@tests::programs::church_exp.snap +++ b/tests/snapshots/run@tests::programs::church_exp.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/church_exp.hvm --- -({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ({2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 a b} c} d} e} f} g} h} i} j} k} l} m} n} o} p} q} r} s} t} u} v} w} x} y} z} aa} ab} ac} ad} ae} af} ag} ah} ai} aj} ak} al} am} an} ao} ap} aq} ar} as} at} au} av} aw} ax} ay} az} ba} bb} bc} bd} be} bf} bg} bh} bi} bj} bk} bl} bm} bn} bo} bp} bq} br} bs} bt} bu} bv} bw} bx} by} bz} ca} cb} cc} cd} ce} cf} cg} ch} ci} cj} ck} cl} cm} cn} co} cp} cq} cr} cs} ct} cu} cv} cw} cx} cy} cz} da} db} dc} dd} de} df} dg} dh} di} dj} dk} dl} dm} dn} do} dp} dq} dr} ds} dt} du} dv} dw} dx} dy} dz} ea} eb} ec} ed} ee} ef} eg} eh} ei} ej} ek} el} em} en} eo} ep} eq} er} es} et} eu} ev} ew} ex} ey} ez} fa} fb} fc} fd} fe} ff} fg} fh} fi} fj} fk} fl} fm} fn} fo} fp} fq} fr} fs} ft} fu} fv} fw} fx} fy} fz} ga} gb} gc} gd} ge} gf} gg} gh} gi} gj} gk} gl} gm} gn} go} gp} gq} gr} gs} gt} gu} gv} gw} gx} gy} gz} ha} hb} hc} hd} he} hf} hg} hh} hi} hj} hk} hl} hm} hn} ho} hp} hq} hr} hs} ht} hu} hv} hw} hx} hy} hz} ia} ib} ic} id} ie} if} ig} ih} ii} ij} ik} il} im} in} io} ip} iq} ir} is} it} iu} iv} iw} ix} iy} iz} ja} jb} jc} jd} je} jf} jg} jh} ji} jj} jk} jl} jm} jn} jo} jp} jq} jr} js} jt} ju} jv} jw} jx} jy} jz} ka} kb} kc} kd} ke} kf} kg} kh} ki} kj} kk} kl} km} kn} ko} kp} kq} kr} ks} kt} ku} kv} kw} kx} ky} kz} la} lb} lc} ld} le} lf} lg} lh} li} lj} lk} ll} lm} ln} lo} lp} lq} lr} ls} lt} lu} lv} lw} lx} ly} lz} ma} mb} mc} md} me} mf} mg} mh} mi} mj} mk} ml} mm} mn} mo} mp} mq} mr} ms} mt} mu} mv} mw} mx} my) (my mz)} (mz na)} (na nb)} (nb nc)} (nc nd)} (nd ne)} (ne nf)} (nf ng)} (ng nh)} (nh ni)} (ni nj)} (nj nk)} (nk nl)} (nl nm)} (nm nn)} (nn no)} (no np)} (np nq)} (nq {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 mf mg} mh} mi} mj} mk} ml} mm} mn} mo} mp} mq} mr} ms} mt} mu} mv} mw} mx} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 lm ln} lo} lp} lq} lr} ls} lt} lu} lv} lw} lx} ly} lz} ma} mb} mc} md} me} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 kt ku} kv} kw} kx} ky} kz} la} lb} lc} ld} le} lf} lg} lh} li} lj} lk} ll} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ka kb} kc} kd} ke} kf} kg} kh} ki} kj} kk} kl} km} kn} ko} kp} kq} kr} ks} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 jh ji} jj} jk} jl} jm} jn} jo} jp} jq} jr} js} jt} ju} jv} jw} jx} jy} jz} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 io ip} iq} ir} is} it} iu} iv} iw} ix} iy} iz} ja} jb} jc} jd} je} jf} jg} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 hv hw} hx} hy} hz} ia} ib} ic} id} ie} if} ig} ih} ii} ij} ik} il} im} in} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 hc hd} he} hf} hg} hh} hi} hj} hk} hl} hm} hn} ho} hp} hq} hr} hs} ht} hu} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 gj gk} gl} gm} gn} go} gp} gq} gr} gs} gt} gu} gv} gw} gx} gy} gz} ha} hb} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 fq fr} fs} ft} fu} fv} fw} fx} fy} fz} ga} gb} gc} gd} ge} gf} gg} gh} gi} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ex ey} ez} fa} fb} fc} fd} fe} ff} fg} fh} fi} fj} fk} fl} fm} fn} fo} fp} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 ee ef} eg} eh} ei} ej} ek} el} em} en} eo} ep} eq} er} es} et} eu} ev} ew} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 dl dm} dn} do} dp} dq} dr} ds} dt} du} dv} dw} dx} dy} dz} ea} eb} ec} ed} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 cs ct} cu} cv} cw} cx} cy} cz} da} db} dc} dd} de} df} dg} dh} di} dj} dk} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 bz ca} cb} cc} cd} ce} cf} cg} ch} ci} cj} ck} cl} cm} cn} co} cp} cq} cr} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 bg bh} bi} bj} bk} bl} bm} bn} bo} bp} bq} br} bs} bt} bu} bv} bw} bx} by} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 an ao} ap} aq} ar} as} at} au} av} aw} ax} ay} az} ba} bb} bc} bd} be} bf} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 u v} w} x} y} z} aa} ab} ac} ad} ae} af} ag} ah} ai} aj} ak} al} am} {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 {2 b c} d} e} f} g} h} i} j} k} l} m} n} o} p} q} r} s} t} nr}}}}}}}}}}}}}}}}}}})} (a nr)) +(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1((#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(a b) c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) s) t) u) v) w) x) y) z) aa) ab) ac) ad) ae) af) ag) ah) ai) aj) ak) al) am) an) ao) ap) aq) ar) as) at) au) av) aw) ax) ay) az) ba) bb) bc) bd) be) bf) bg) bh) bi) bj) bk) bl) bm) bn) bo) bp) bq) br) bs) bt) bu) bv) bw) bx) by) bz) ca) cb) cc) cd) ce) cf) cg) ch) ci) cj) ck) cl) cm) cn) co) cp) cq) cr) cs) ct) cu) cv) cw) cx) cy) cz) da) db) dc) dd) de) df) dg) dh) di) dj) dk) dl) dm) dn) do) dp) dq) dr) ds) dt) du) dv) dw) dx) dy) dz) ea) eb) ec) ed) ee) ef) eg) eh) ei) ej) ek) el) em) en) eo) ep) eq) er) es) et) eu) ev) ew) ex) ey) ez) fa) fb) fc) fd) fe) ff) fg) fh) fi) fj) fk) fl) fm) fn) fo) fp) fq) fr) fs) ft) fu) fv) fw) fx) fy) fz) ga) gb) gc) gd) ge) gf) gg) gh) gi) gj) gk) gl) gm) gn) go) gp) gq) gr) gs) gt) gu) gv) gw) gx) gy) gz) ha) hb) hc) hd) he) hf) hg) hh) hi) hj) hk) hl) hm) hn) ho) hp) hq) hr) hs) ht) hu) hv) hw) hx) hy) hz) ia) ib) ic) id) ie) if) ig) ih) ii) ij) ik) il) im) in) io) ip) iq) ir) is) it) iu) iv) iw) ix) iy) iz) ja) jb) jc) jd) je) jf) jg) jh) ji) jj) jk) jl) jm) jn) jo) jp) jq) jr) js) jt) ju) jv) jw) jx) jy) jz) ka) kb) kc) kd) ke) kf) kg) kh) ki) kj) kk) kl) km) kn) ko) kp) kq) kr) ks) kt) ku) kv) kw) kx) ky) kz) la) lb) lc) ld) le) lf) lg) lh) li) lj) lk) ll) lm) ln) lo) lp) lq) lr) ls) lt) lu) lv) lw) lx) ly) lz) ma) mb) mc) md) me) mf) mg) mh) mi) mj) mk) ml) mm) mn) mo) mp) mq) mr) ms) mt) mu) mv) mw) mx) my) (my mz)) (mz na)) (na nb)) (nb nc)) (nc nd)) (nd ne)) (ne nf)) (nf ng)) (ng nh)) (nh ni)) (ni nj)) (nj nk)) (nk nl)) (nl nm)) (nm nn)) (nn no)) (no np)) (np nq)) (nq #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(mf mg) mh) mi) mj) mk) ml) mm) mn) mo) mp) mq) mr) ms) mt) mu) mv) mw) mx) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(lm ln) lo) lp) lq) lr) ls) lt) lu) lv) lw) lx) ly) lz) ma) mb) mc) md) me) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(kt ku) kv) kw) kx) ky) kz) la) lb) lc) ld) le) lf) lg) lh) li) lj) lk) ll) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ka kb) kc) kd) ke) kf) kg) kh) ki) kj) kk) kl) km) kn) ko) kp) kq) kr) ks) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(jh ji) jj) jk) jl) jm) jn) jo) jp) jq) jr) js) jt) ju) jv) jw) jx) jy) jz) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(io ip) iq) ir) is) it) iu) iv) iw) ix) iy) iz) ja) jb) jc) jd) je) jf) jg) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(hv hw) hx) hy) hz) ia) ib) ic) id) ie) if) ig) ih) ii) ij) ik) il) im) in) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(hc hd) he) hf) hg) hh) hi) hj) hk) hl) hm) hn) ho) hp) hq) hr) hs) ht) hu) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(gj gk) gl) gm) gn) go) gp) gq) gr) gs) gt) gu) gv) gw) gx) gy) gz) ha) hb) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(fq fr) fs) ft) fu) fv) fw) fx) fy) fz) ga) gb) gc) gd) ge) gf) gg) gh) gi) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ex ey) ez) fa) fb) fc) fd) fe) ff) fg) fh) fi) fj) fk) fl) fm) fn) fo) fp) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(ee ef) eg) eh) ei) ej) ek) el) em) en) eo) ep) eq) er) es) et) eu) ev) ew) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(dl dm) dn) do) dp) dq) dr) ds) dt) du) dv) dw) dx) dy) dz) ea) eb) ec) ed) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(cs ct) cu) cv) cw) cx) cy) cz) da) db) dc) dd) de) df) dg) dh) di) dj) dk) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(bz ca) cb) cc) cd) ce) cf) cg) ch) ci) cj) ck) cl) cm) cn) co) cp) cq) cr) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(bg bh) bi) bj) bk) bl) bm) bn) bo) bp) bq) br) bs) bt) bu) bv) bw) bx) by) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(an ao) ap) aq) ar) as) at) au) av) aw) ax) ay) az) ba) bb) bc) bd) be) bf) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(u v) w) x) y) z) aa) ab) ac) ad) ae) af) ag) ah) ai) aj) ak) al) am) #1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(#1(b c) d) e) f) g) h) i) j) k) l) m) n) o) p) q) r) s) t) nr))))))))))))))))))))) (a nr)) RWTS : 1_948 - ANNI : 401 - COMM : 380 diff --git a/tests/snapshots/run@tests::programs::church_mul.snap b/tests/snapshots/run@tests::programs::church_mul.snap index 1afb51b6..3cbeef8b 100644 --- a/tests/snapshots/run@tests::programs::church_mul.snap +++ b/tests/snapshots/run@tests::programs::church_mul.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/church_mul.hvm --- -({3 (a {3 b {3 c {3 d {3 e {3 f {3 g {3 h {3 i {3 j {3 k {3 l {3 m {3 n {3 o {3 p {3 q {3 r {3 s {3 t u}}}}}}}}}}}}}}}}}}}) {3 (v a) {3 (w v) {3 (x w) {3 (y x) {3 (z y) {3 (aa z) {3 (ab aa) {3 (ac ab) {3 (ad ac) {3 (ae ad) {3 (af ae) {3 (ag af) {3 (ah ag) {3 (ai ah) {3 (aj ai) {3 (ak aj) {3 (al ak) {3 (am al) ({3 c {3 d {3 e {3 f {3 g {3 h {3 i {3 j {3 k {3 l {3 m {3 n {3 o {3 p {3 q {3 r {3 s {3 t {3 u an}}}}}}}}}}}}}}}}}}} am)}}}}}}}}}}}}}}}}}}} (an b)) +(#1{(a #1{b #1{c #1{d #1{e #1{f #1{g #1{h #1{i #1{j #1{k #1{l #1{m #1{n #1{o #1{p #1{q #1{r #1{s #1{t u}}}}}}}}}}}}}}}}}}}) #1{(v a) #1{(w v) #1{(x w) #1{(y x) #1{(z y) #1{(aa z) #1{(ab aa) #1{(ac ab) #1{(ad ac) #1{(ae ad) #1{(af ae) #1{(ag af) #1{(ah ag) #1{(ai ah) #1{(aj ai) #1{(ak aj) #1{(al ak) #1{(am al) (#1{c #1{d #1{e #1{f #1{g #1{h #1{i #1{j #1{k #1{l #1{m #1{n #1{o #1{p #1{q #1{r #1{s #1{t #1{u an}}}}}}}}}}}}}}}}}}} am)}}}}}}}}}}}}}}}}}}} (an b)) RWTS : 167 - ANNI : 25 - COMM : 19 diff --git a/tests/snapshots/run@tests::programs::f24.snap b/tests/snapshots/run@tests::programs::f24.snap new file mode 100644 index 00000000..464d3254 --- /dev/null +++ b/tests/snapshots/run@tests::programs::f24.snap @@ -0,0 +1,12 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/f24.hvm +--- +{+inf {-inf {+NaN {2.5 {-1.5 {1.1499939 {0.25 {0.5 {0 {1 {1 {0 {0 {0 {0 {+NaN {+inf {-inf {1.019989 {0.1000061 {0.1000061 {-0.1000061 {-0.1000061 *}}}}}}}}}}}}}}}}}}}}}}} +RWTS : 174 +- ANNI : 23 +- COMM : 1 +- ERAS : 24 +- DREF : 88 +- OPER : 38 diff --git a/tests/snapshots/run@tests::programs::f32.snap b/tests/snapshots/run@tests::programs::f32.snap deleted file mode 100644 index 62f234b6..00000000 --- a/tests/snapshots/run@tests::programs::f32.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/f32.hvm ---- -[#inf [#-inf [#NaN [#2.5 [#-1.5 [#1.15 [#0.25 [#0.5 [#0 [#1 [#1 [#0 [#0 [#0 [#0 [#0 [#0 [#NaN [#inf [#-inf [#1.02 *]]]]]]]]]]]]]]]]]]]]] -RWTS : 103 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 63 -- OPER : 40 diff --git a/tests/snapshots/run@tests::programs::i24.snap b/tests/snapshots/run@tests::programs::i24.snap new file mode 100644 index 00000000..70df3881 --- /dev/null +++ b/tests/snapshots/run@tests::programs::i24.snap @@ -0,0 +1,12 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/i24.hvm +--- +{+12 {+8 {+20 {+5 {+0 {0 {1 {0 {1 {+2 {+10 {+8 {+8388607 {-8388608 {+1 {+1 {-1 {-1 *}}}}}}}}}}}}}}}}}} +RWTS : 114 +- ANNI : 18 +- COMM : 1 +- ERAS : 19 +- DREF : 58 +- OPER : 18 diff --git a/tests/snapshots/run@tests::programs::list_put_got.snap b/tests/snapshots/run@tests::programs::list_put_got.snap index a36a905c..fe26b1dd 100644 --- a/tests/snapshots/run@tests::programs::list_put_got.snap +++ b/tests/snapshots/run@tests::programs::list_put_got.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/list_put_got.hvm --- -(((* (((* (((* (a a)) b) b)) ((* (((* (((((* (c c)) d) (* d)) e) e)) ((* (((* (((((((* (f f)) g) (* g)) h) (* h)) i) i)) ((* (((* (((((((((* (j j)) k) (* k)) l) (* l)) m) (* m)) n) n)) ((* (((* (((((((((((* (o o)) p) (* p)) q) (* q)) r) (* r)) s) (* s)) t) t)) ((* (((* (((((((((((((* (u u)) v) (* v)) w) (* w)) x) (* x)) y) (* y)) z) (* z)) aa) aa)) ((* (((* (((((((((((((((* (ab ab)) ac) (* ac)) ad) (* ad)) ae) (* ae)) af) (* af)) ag) (* ag)) ah) (* ah)) ai) ai)) ((* (((* (((((((((((((((((* (aj aj)) ak) (* ak)) al) (* al)) am) (* am)) an) (* an)) ao) (* ao)) ap) (* ap)) aq) (* aq)) ar) ar)) ((* (((* (((((((((((((((((((* (as as)) at) (* at)) au) (* au)) av) (* av)) aw) (* aw)) ax) (* ax)) ay) (* ay)) az) (* az)) ba) (* ba)) bb) bb)) ((* (((* (((((((((((((((((((((* (bc bc)) bd) (* bd)) be) (* be)) bf) (* bf)) bg) (* bg)) bh) (* bh)) bi) (* bi)) bj) (* bj)) bk) (* bk)) bl) (* bl)) bm) bm)) ((* (((* (((((((((((((((((((((((* (bn bn)) bo) (* bo)) bp) (* bp)) bq) (* bq)) br) (* br)) bs) (* bs)) bt) (* bt)) bu) (* bu)) bv) (* bv)) bw) (* bw)) bx) (* bx)) by) by)) ((* (((* (((((((((((((((((((((((((* (bz bz)) ca) (* ca)) cb) (* cb)) cc) (* cc)) cd) (* cd)) ce) (* ce)) cf) (* cf)) cg) (* cg)) ch) (* ch)) ci) (* ci)) cj) (* cj)) ck) (* ck)) cl) cl)) ((* (((* (((((((((((((((((((((((((((* (cm cm)) cn) (* cn)) co) (* co)) cp) (* cp)) cq) (* cq)) cr) (* cr)) cs) (* cs)) ct) (* ct)) cu) (* cu)) cv) (* cv)) cw) (* cw)) cx) (* cx)) cy) (* cy)) cz) cz)) ((* (((* (((((((((((((((((((((((((((((* (da da)) db) (* db)) dc) (* dc)) dd) (* dd)) de) (* de)) df) (* df)) dg) (* dg)) dh) (* dh)) di) (* di)) dj) (* dj)) dk) (* dk)) dl) (* dl)) dm) (* dm)) dn) (* dn)) do) do)) ((* (((* (((((((((((((((((((((((((((((((* (dp dp)) dq) (* dq)) dr) (* dr)) ds) (* ds)) dt) (* dt)) du) (* du)) dv) (* dv)) dw) (* dw)) dx) (* dx)) dy) (* dy)) dz) (* dz)) ea) (* ea)) eb) (* eb)) ec) (* ec)) ed) (* ed)) ee) ee)) ((* (((* (((((((((((((((((((((((((((((((((* (ef ef)) eg) (* eg)) eh) (* eh)) ei) (* ei)) ej) (* ej)) ek) (* ek)) el) (* el)) em) (* em)) en) (* en)) eo) (* eo)) ep) (* ep)) eq) (* eq)) er) (* er)) es) (* es)) et) (* et)) eu) (* eu)) ev) ev)) ((* (((* (((((((((((((((((((((((((((((((((((* (ew ew)) ex) (* ex)) ey) (* ey)) ez) (* ez)) fa) (* fa)) fb) (* fb)) fc) (* fc)) fd) (* fd)) fe) (* fe)) ff) (* ff)) fg) (* fg)) fh) (* fh)) fi) (* fi)) fj) (* fj)) fk) (* fk)) fl) (* fl)) fm) (* fm)) fn) fn)) ((* (((* (((((((((((((((((((((((((((((((((((((* (fo fo)) fp) (* fp)) fq) (* fq)) fr) (* fr)) fs) (* fs)) ft) (* ft)) fu) (* fu)) fv) (* fv)) fw) (* fw)) fx) (* fx)) fy) (* fy)) fz) (* fz)) ga) (* ga)) gb) (* gb)) gc) (* gc)) gd) (* gd)) ge) (* ge)) gf) (* gf)) gg) gg)) ((* (((* (((((((((((((((((((((((((((((((((((((((* (gh gh)) gi) (* gi)) gj) (* gj)) gk) (* gk)) gl) (* gl)) gm) (* gm)) gn) (* gn)) go) (* go)) gp) (* gp)) gq) (* gq)) gr) (* gr)) gs) (* gs)) gt) (* gt)) gu) (* gu)) gv) (* gv)) gw) (* gw)) gx) (* gx)) gy) (* gy)) gz) (* gz)) ha) ha)) ((* (((* (((((((((((((((((((((((((((((((((((((((((* (hb hb)) hc) (* hc)) hd) (* hd)) he) (* he)) hf) (* hf)) hg) (* hg)) hh) (* hh)) hi) (* hi)) hj) (* hj)) hk) (* hk)) hl) (* hl)) hm) (* hm)) hn) (* hn)) ho) (* ho)) hp) (* hp)) hq) (* hq)) hr) (* hr)) hs) (* hs)) ht) (* ht)) hu) (* hu)) hv) hv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((* (hw hw)) hx) (* hx)) hy) (* hy)) hz) (* hz)) ia) (* ia)) ib) (* ib)) ic) (* ic)) id) (* id)) ie) (* ie)) if) (* if)) ig) (* ig)) ih) (* ih)) ii) (* ii)) ij) (* ij)) ik) (* ik)) il) (* il)) im) (* im)) in) (* in)) io) (* io)) ip) (* ip)) iq) (* iq)) ir) ir)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((* (is is)) it) (* it)) iu) (* iu)) iv) (* iv)) iw) (* iw)) ix) (* ix)) iy) (* iy)) iz) (* iz)) ja) (* ja)) jb) (* jb)) jc) (* jc)) jd) (* jd)) je) (* je)) jf) (* jf)) jg) (* jg)) jh) (* jh)) ji) (* ji)) jj) (* jj)) jk) (* jk)) jl) (* jl)) jm) (* jm)) jn) (* jn)) jo) jo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((* (jp jp)) jq) (* jq)) jr) (* jr)) js) (* js)) jt) (* jt)) ju) (* ju)) jv) (* jv)) jw) (* jw)) jx) (* jx)) jy) (* jy)) jz) (* jz)) ka) (* ka)) kb) (* kb)) kc) (* kc)) kd) (* kd)) ke) (* ke)) kf) (* kf)) kg) (* kg)) kh) (* kh)) ki) (* ki)) kj) (* kj)) kk) (* kk)) kl) (* kl)) km) km)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((* (kn kn)) ko) (* ko)) kp) (* kp)) kq) (* kq)) kr) (* kr)) ks) (* ks)) kt) (* kt)) ku) (* ku)) kv) (* kv)) kw) (* kw)) kx) (* kx)) ky) (* ky)) kz) (* kz)) la) (* la)) lb) (* lb)) lc) (* lc)) ld) (* ld)) le) (* le)) lf) (* lf)) lg) (* lg)) lh) (* lh)) li) (* li)) lj) (* lj)) lk) (* lk)) ll) ll)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((* (lm lm)) ln) (* ln)) lo) (* lo)) lp) (* lp)) lq) (* lq)) lr) (* lr)) ls) (* ls)) lt) (* lt)) lu) (* lu)) lv) (* lv)) lw) (* lw)) lx) (* lx)) ly) (* ly)) lz) (* lz)) ma) (* ma)) mb) (* mb)) mc) (* mc)) md) (* md)) me) (* me)) mf) (* mf)) mg) (* mg)) mh) (* mh)) mi) (* mi)) mj) (* mj)) mk) (* mk)) ml) ml)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((* (mm mm)) mn) (* mn)) mo) (* mo)) mp) (* mp)) mq) (* mq)) mr) (* mr)) ms) (* ms)) mt) (* mt)) mu) (* mu)) mv) (* mv)) mw) (* mw)) mx) (* mx)) my) (* my)) mz) (* mz)) na) (* na)) nb) (* nb)) nc) (* nc)) nd) (* nd)) ne) (* ne)) nf) (* nf)) ng) (* ng)) nh) (* nh)) ni) (* ni)) nj) (* nj)) nk) (* nk)) nl) (* nl)) nm) nm)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((* (nn nn)) no) (* no)) np) (* np)) nq) (* nq)) nr) (* nr)) ns) (* ns)) nt) (* nt)) nu) (* nu)) nv) (* nv)) nw) (* nw)) nx) (* nx)) ny) (* ny)) nz) (* nz)) oa) (* oa)) ob) (* ob)) oc) (* oc)) od) (* od)) oe) (* oe)) of) (* of)) og) (* og)) oh) (* oh)) oi) (* oi)) oj) (* oj)) ok) (* ok)) ol) (* ol)) om) (* om)) on) (* on)) oo) oo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (op op)) oq) (* oq)) or) (* or)) os) (* os)) ot) (* ot)) ou) (* ou)) ov) (* ov)) ow) (* ow)) ox) (* ox)) oy) (* oy)) oz) (* oz)) pa) (* pa)) pb) (* pb)) pc) (* pc)) pd) (* pd)) pe) (* pe)) pf) (* pf)) pg) (* pg)) ph) (* ph)) pi) (* pi)) pj) (* pj)) pk) (* pk)) pl) (* pl)) pm) (* pm)) pn) (* pn)) po) (* po)) pp) (* pp)) pq) (* pq)) pr) pr)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (ps ps)) pt) (* pt)) pu) (* pu)) pv) (* pv)) pw) (* pw)) px) (* px)) py) (* py)) pz) (* pz)) qa) (* qa)) qb) (* qb)) qc) (* qc)) qd) (* qd)) qe) (* qe)) qf) (* qf)) qg) (* qg)) qh) (* qh)) qi) (* qi)) qj) (* qj)) qk) (* qk)) ql) (* ql)) qm) (* qm)) qn) (* qn)) qo) (* qo)) qp) (* qp)) qq) (* qq)) qr) (* qr)) qs) (* qs)) qt) (* qt)) qu) (* qu)) qv) qv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (qw qw)) qx) (* qx)) qy) (* qy)) qz) (* qz)) ra) (* ra)) rb) (* rb)) rc) (* rc)) rd) (* rd)) re) (* re)) rf) (* rf)) rg) (* rg)) rh) (* rh)) ri) (* ri)) rj) (* rj)) rk) (* rk)) rl) (* rl)) rm) (* rm)) rn) (* rn)) ro) (* ro)) rp) (* rp)) rq) (* rq)) rr) (* rr)) rs) (* rs)) rt) (* rt)) ru) (* ru)) rv) (* rv)) rw) (* rw)) rx) (* rx)) ry) (* ry)) rz) (* rz)) sa) sa)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (sb sb)) sc) (* sc)) sd) (* sd)) se) (* se)) sf) (* sf)) sg) (* sg)) sh) (* sh)) si) (* si)) sj) (* sj)) sk) (* sk)) sl) (* sl)) sm) (* sm)) sn) (* sn)) so) (* so)) sp) (* sp)) sq) (* sq)) sr) (* sr)) ss) (* ss)) st) (* st)) su) (* su)) sv) (* sv)) sw) (* sw)) sx) (* sx)) sy) (* sy)) sz) (* sz)) ta) (* ta)) tb) (* tb)) tc) (* tc)) td) (* td)) te) (* te)) tf) (* tf)) tg) tg)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (th th)) ti) (* ti)) tj) (* tj)) tk) (* tk)) tl) (* tl)) tm) (* tm)) tn) (* tn)) to) (* to)) tp) (* tp)) tq) (* tq)) tr) (* tr)) ts) (* ts)) tt) (* tt)) tu) (* tu)) tv) (* tv)) tw) (* tw)) tx) (* tx)) ty) (* ty)) tz) (* tz)) ua) (* ua)) ub) (* ub)) uc) (* uc)) ud) (* ud)) ue) (* ue)) uf) (* uf)) ug) (* ug)) uh) (* uh)) ui) (* ui)) uj) (* uj)) uk) (* uk)) ul) (* ul)) um) (* um)) un) un)) ((uo (* uo)) up)) up)) uq)) uq)) ur)) ur)) us)) us)) ut)) ut)) uu)) uu)) uv)) uv)) uw)) uw)) ux)) ux)) uy)) uy)) uz)) uz)) va)) va)) vb)) vb)) vc)) vc)) vd)) vd)) ve)) ve)) vf)) vf)) vg)) vg)) vh)) vh)) vi)) vi)) vj)) vj)) vk)) vk)) vl)) vl)) vm)) vm)) vn)) vn)) vo)) vo)) vp)) vp)) vq)) vq)) vr)) vr)) vs)) vs)) vt)) vt)) vu)) vu)) [vv *]) vv) +(((* (((* (((* (a a)) b) b)) ((* (((* (((((* (c c)) d) (* d)) e) e)) ((* (((* (((((((* (f f)) g) (* g)) h) (* h)) i) i)) ((* (((* (((((((((* (j j)) k) (* k)) l) (* l)) m) (* m)) n) n)) ((* (((* (((((((((((* (o o)) p) (* p)) q) (* q)) r) (* r)) s) (* s)) t) t)) ((* (((* (((((((((((((* (u u)) v) (* v)) w) (* w)) x) (* x)) y) (* y)) z) (* z)) aa) aa)) ((* (((* (((((((((((((((* (ab ab)) ac) (* ac)) ad) (* ad)) ae) (* ae)) af) (* af)) ag) (* ag)) ah) (* ah)) ai) ai)) ((* (((* (((((((((((((((((* (aj aj)) ak) (* ak)) al) (* al)) am) (* am)) an) (* an)) ao) (* ao)) ap) (* ap)) aq) (* aq)) ar) ar)) ((* (((* (((((((((((((((((((* (as as)) at) (* at)) au) (* au)) av) (* av)) aw) (* aw)) ax) (* ax)) ay) (* ay)) az) (* az)) ba) (* ba)) bb) bb)) ((* (((* (((((((((((((((((((((* (bc bc)) bd) (* bd)) be) (* be)) bf) (* bf)) bg) (* bg)) bh) (* bh)) bi) (* bi)) bj) (* bj)) bk) (* bk)) bl) (* bl)) bm) bm)) ((* (((* (((((((((((((((((((((((* (bn bn)) bo) (* bo)) bp) (* bp)) bq) (* bq)) br) (* br)) bs) (* bs)) bt) (* bt)) bu) (* bu)) bv) (* bv)) bw) (* bw)) bx) (* bx)) by) by)) ((* (((* (((((((((((((((((((((((((* (bz bz)) ca) (* ca)) cb) (* cb)) cc) (* cc)) cd) (* cd)) ce) (* ce)) cf) (* cf)) cg) (* cg)) ch) (* ch)) ci) (* ci)) cj) (* cj)) ck) (* ck)) cl) cl)) ((* (((* (((((((((((((((((((((((((((* (cm cm)) cn) (* cn)) co) (* co)) cp) (* cp)) cq) (* cq)) cr) (* cr)) cs) (* cs)) ct) (* ct)) cu) (* cu)) cv) (* cv)) cw) (* cw)) cx) (* cx)) cy) (* cy)) cz) cz)) ((* (((* (((((((((((((((((((((((((((((* (da da)) db) (* db)) dc) (* dc)) dd) (* dd)) de) (* de)) df) (* df)) dg) (* dg)) dh) (* dh)) di) (* di)) dj) (* dj)) dk) (* dk)) dl) (* dl)) dm) (* dm)) dn) (* dn)) do) do)) ((* (((* (((((((((((((((((((((((((((((((* (dp dp)) dq) (* dq)) dr) (* dr)) ds) (* ds)) dt) (* dt)) du) (* du)) dv) (* dv)) dw) (* dw)) dx) (* dx)) dy) (* dy)) dz) (* dz)) ea) (* ea)) eb) (* eb)) ec) (* ec)) ed) (* ed)) ee) ee)) ((* (((* (((((((((((((((((((((((((((((((((* (ef ef)) eg) (* eg)) eh) (* eh)) ei) (* ei)) ej) (* ej)) ek) (* ek)) el) (* el)) em) (* em)) en) (* en)) eo) (* eo)) ep) (* ep)) eq) (* eq)) er) (* er)) es) (* es)) et) (* et)) eu) (* eu)) ev) ev)) ((* (((* (((((((((((((((((((((((((((((((((((* (ew ew)) ex) (* ex)) ey) (* ey)) ez) (* ez)) fa) (* fa)) fb) (* fb)) fc) (* fc)) fd) (* fd)) fe) (* fe)) ff) (* ff)) fg) (* fg)) fh) (* fh)) fi) (* fi)) fj) (* fj)) fk) (* fk)) fl) (* fl)) fm) (* fm)) fn) fn)) ((* (((* (((((((((((((((((((((((((((((((((((((* (fo fo)) fp) (* fp)) fq) (* fq)) fr) (* fr)) fs) (* fs)) ft) (* ft)) fu) (* fu)) fv) (* fv)) fw) (* fw)) fx) (* fx)) fy) (* fy)) fz) (* fz)) ga) (* ga)) gb) (* gb)) gc) (* gc)) gd) (* gd)) ge) (* ge)) gf) (* gf)) gg) gg)) ((* (((* (((((((((((((((((((((((((((((((((((((((* (gh gh)) gi) (* gi)) gj) (* gj)) gk) (* gk)) gl) (* gl)) gm) (* gm)) gn) (* gn)) go) (* go)) gp) (* gp)) gq) (* gq)) gr) (* gr)) gs) (* gs)) gt) (* gt)) gu) (* gu)) gv) (* gv)) gw) (* gw)) gx) (* gx)) gy) (* gy)) gz) (* gz)) ha) ha)) ((* (((* (((((((((((((((((((((((((((((((((((((((((* (hb hb)) hc) (* hc)) hd) (* hd)) he) (* he)) hf) (* hf)) hg) (* hg)) hh) (* hh)) hi) (* hi)) hj) (* hj)) hk) (* hk)) hl) (* hl)) hm) (* hm)) hn) (* hn)) ho) (* ho)) hp) (* hp)) hq) (* hq)) hr) (* hr)) hs) (* hs)) ht) (* ht)) hu) (* hu)) hv) hv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((* (hw hw)) hx) (* hx)) hy) (* hy)) hz) (* hz)) ia) (* ia)) ib) (* ib)) ic) (* ic)) id) (* id)) ie) (* ie)) if) (* if)) ig) (* ig)) ih) (* ih)) ii) (* ii)) ij) (* ij)) ik) (* ik)) il) (* il)) im) (* im)) in) (* in)) io) (* io)) ip) (* ip)) iq) (* iq)) ir) ir)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((* (is is)) it) (* it)) iu) (* iu)) iv) (* iv)) iw) (* iw)) ix) (* ix)) iy) (* iy)) iz) (* iz)) ja) (* ja)) jb) (* jb)) jc) (* jc)) jd) (* jd)) je) (* je)) jf) (* jf)) jg) (* jg)) jh) (* jh)) ji) (* ji)) jj) (* jj)) jk) (* jk)) jl) (* jl)) jm) (* jm)) jn) (* jn)) jo) jo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((* (jp jp)) jq) (* jq)) jr) (* jr)) js) (* js)) jt) (* jt)) ju) (* ju)) jv) (* jv)) jw) (* jw)) jx) (* jx)) jy) (* jy)) jz) (* jz)) ka) (* ka)) kb) (* kb)) kc) (* kc)) kd) (* kd)) ke) (* ke)) kf) (* kf)) kg) (* kg)) kh) (* kh)) ki) (* ki)) kj) (* kj)) kk) (* kk)) kl) (* kl)) km) km)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((* (kn kn)) ko) (* ko)) kp) (* kp)) kq) (* kq)) kr) (* kr)) ks) (* ks)) kt) (* kt)) ku) (* ku)) kv) (* kv)) kw) (* kw)) kx) (* kx)) ky) (* ky)) kz) (* kz)) la) (* la)) lb) (* lb)) lc) (* lc)) ld) (* ld)) le) (* le)) lf) (* lf)) lg) (* lg)) lh) (* lh)) li) (* li)) lj) (* lj)) lk) (* lk)) ll) ll)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((* (lm lm)) ln) (* ln)) lo) (* lo)) lp) (* lp)) lq) (* lq)) lr) (* lr)) ls) (* ls)) lt) (* lt)) lu) (* lu)) lv) (* lv)) lw) (* lw)) lx) (* lx)) ly) (* ly)) lz) (* lz)) ma) (* ma)) mb) (* mb)) mc) (* mc)) md) (* md)) me) (* me)) mf) (* mf)) mg) (* mg)) mh) (* mh)) mi) (* mi)) mj) (* mj)) mk) (* mk)) ml) ml)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((* (mm mm)) mn) (* mn)) mo) (* mo)) mp) (* mp)) mq) (* mq)) mr) (* mr)) ms) (* ms)) mt) (* mt)) mu) (* mu)) mv) (* mv)) mw) (* mw)) mx) (* mx)) my) (* my)) mz) (* mz)) na) (* na)) nb) (* nb)) nc) (* nc)) nd) (* nd)) ne) (* ne)) nf) (* nf)) ng) (* ng)) nh) (* nh)) ni) (* ni)) nj) (* nj)) nk) (* nk)) nl) (* nl)) nm) nm)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((* (nn nn)) no) (* no)) np) (* np)) nq) (* nq)) nr) (* nr)) ns) (* ns)) nt) (* nt)) nu) (* nu)) nv) (* nv)) nw) (* nw)) nx) (* nx)) ny) (* ny)) nz) (* nz)) oa) (* oa)) ob) (* ob)) oc) (* oc)) od) (* od)) oe) (* oe)) of) (* of)) og) (* og)) oh) (* oh)) oi) (* oi)) oj) (* oj)) ok) (* ok)) ol) (* ol)) om) (* om)) on) (* on)) oo) oo)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (op op)) oq) (* oq)) or) (* or)) os) (* os)) ot) (* ot)) ou) (* ou)) ov) (* ov)) ow) (* ow)) ox) (* ox)) oy) (* oy)) oz) (* oz)) pa) (* pa)) pb) (* pb)) pc) (* pc)) pd) (* pd)) pe) (* pe)) pf) (* pf)) pg) (* pg)) ph) (* ph)) pi) (* pi)) pj) (* pj)) pk) (* pk)) pl) (* pl)) pm) (* pm)) pn) (* pn)) po) (* po)) pp) (* pp)) pq) (* pq)) pr) pr)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (ps ps)) pt) (* pt)) pu) (* pu)) pv) (* pv)) pw) (* pw)) px) (* px)) py) (* py)) pz) (* pz)) qa) (* qa)) qb) (* qb)) qc) (* qc)) qd) (* qd)) qe) (* qe)) qf) (* qf)) qg) (* qg)) qh) (* qh)) qi) (* qi)) qj) (* qj)) qk) (* qk)) ql) (* ql)) qm) (* qm)) qn) (* qn)) qo) (* qo)) qp) (* qp)) qq) (* qq)) qr) (* qr)) qs) (* qs)) qt) (* qt)) qu) (* qu)) qv) qv)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (qw qw)) qx) (* qx)) qy) (* qy)) qz) (* qz)) ra) (* ra)) rb) (* rb)) rc) (* rc)) rd) (* rd)) re) (* re)) rf) (* rf)) rg) (* rg)) rh) (* rh)) ri) (* ri)) rj) (* rj)) rk) (* rk)) rl) (* rl)) rm) (* rm)) rn) (* rn)) ro) (* ro)) rp) (* rp)) rq) (* rq)) rr) (* rr)) rs) (* rs)) rt) (* rt)) ru) (* ru)) rv) (* rv)) rw) (* rw)) rx) (* rx)) ry) (* ry)) rz) (* rz)) sa) sa)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (sb sb)) sc) (* sc)) sd) (* sd)) se) (* se)) sf) (* sf)) sg) (* sg)) sh) (* sh)) si) (* si)) sj) (* sj)) sk) (* sk)) sl) (* sl)) sm) (* sm)) sn) (* sn)) so) (* so)) sp) (* sp)) sq) (* sq)) sr) (* sr)) ss) (* ss)) st) (* st)) su) (* su)) sv) (* sv)) sw) (* sw)) sx) (* sx)) sy) (* sy)) sz) (* sz)) ta) (* ta)) tb) (* tb)) tc) (* tc)) td) (* td)) te) (* te)) tf) (* tf)) tg) tg)) ((* (((* (((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((* (th th)) ti) (* ti)) tj) (* tj)) tk) (* tk)) tl) (* tl)) tm) (* tm)) tn) (* tn)) to) (* to)) tp) (* tp)) tq) (* tq)) tr) (* tr)) ts) (* ts)) tt) (* tt)) tu) (* tu)) tv) (* tv)) tw) (* tw)) tx) (* tx)) ty) (* ty)) tz) (* tz)) ua) (* ua)) ub) (* ub)) uc) (* uc)) ud) (* ud)) ue) (* ue)) uf) (* uf)) ug) (* ug)) uh) (* uh)) ui) (* ui)) uj) (* uj)) uk) (* uk)) ul) (* ul)) um) (* um)) un) un)) ((uo (* uo)) up)) up)) uq)) uq)) ur)) ur)) us)) us)) ut)) ut)) uu)) uu)) uv)) uv)) uw)) uw)) ux)) ux)) uy)) uy)) uz)) uz)) va)) va)) vb)) vb)) vc)) vc)) vd)) vd)) ve)) ve)) vf)) vf)) vg)) vg)) vh)) vh)) vi)) vi)) vj)) vj)) vk)) vk)) vl)) vl)) vm)) vm)) vn)) vn)) vo)) vo)) vp)) vp)) vq)) vq)) vr)) vr)) vs)) vs)) vt)) vt)) vu)) vu)) {vv *}) vv) RWTS : 4_188 - ANNI : 96 - COMM : 0 diff --git a/tests/snapshots/run@tests::programs::numeric_casts.snap b/tests/snapshots/run@tests::programs::numeric_casts.snap new file mode 100644 index 00000000..a8eab097 --- /dev/null +++ b/tests/snapshots/run@tests::programs::numeric_casts.snap @@ -0,0 +1,12 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/numeric_casts.hvm +--- +{0 {1234 {4321 {16771538 {2 {0 {16777215 {16777215 {0 {0 {+0 {+1234 {+4321 {-5678 {+2 {-12 {+8388607 {-8388608 {+8388607 {-8388608 {+0 {+NaN {+inf {-inf {2.1500244 {-2.1500244 {0.15000153 {-1234.0 {1234.0 {123456.0 {16775936.0 {[u24] {[i24] {[f24] *}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +RWTS : 207 +- ANNI : 34 +- COMM : 1 +- ERAS : 35 +- DREF : 106 +- OPER : 31 diff --git a/tests/snapshots/run@tests::programs::nums.snap b/tests/snapshots/run@tests::programs::nums.snap deleted file mode 100644 index bd5d8dc6..00000000 --- a/tests/snapshots/run@tests::programs::nums.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/nums.hvm ---- -[#12345 [#0 [#0 [#-12345 [#2748 [#-2748 [#10 [#-10 [#1.0 [#0.1 [#0.001 [#-123.123 [#-1204.5 [#NaN [#NaN [#inf [#-inf *]]]]]]]]]]]]]]]]] -RWTS : 36 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 36 -- OPER : 0 diff --git a/tests/snapshots/run@tests::programs::ops.snap b/tests/snapshots/run@tests::programs::ops.snap deleted file mode 100644 index cf9af005..00000000 --- a/tests/snapshots/run@tests::programs::ops.snap +++ /dev/null @@ -1,12 +0,0 @@ ---- -source: tests/tests.rs -expression: output -input_file: tests/programs/ops.hvm ---- -[#255 [#65535 [#4294967295 [#-1 [#255 [#65535 [#4294967295 [#-1 [#0 [#0 [#0 [#0 [#-1 [#-1 [#-1 [#-2 [#-2 [#-2 [#12 [#8 [#20 [#5 [#0 [#0 [#1 [#0 [#1 [#2 [#10 [#8 [#40 [#2 [#0 *]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] -RWTS : 101 -- ANNI : 0 -- COMM : 0 -- ERAS : 0 -- DREF : 68 -- OPER : 33 diff --git a/tests/snapshots/run@tests::programs::queue.snap b/tests/snapshots/run@tests::programs::queue.snap index c480c212..e1379a66 100644 --- a/tests/snapshots/run@tests::programs::queue.snap +++ b/tests/snapshots/run@tests::programs::queue.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/queue.hvm --- -(((* (a a)) (((((b c) (b c)) (((({3 (d e) (f d)} (f e)) ((* (g g)) h)) (* h)) i)) (* i)) j)) (* j)) +(((* (a a)) (((((b c) (b c)) ((((#1{(d e) (f d)} (f e)) ((* (g g)) h)) (* h)) i)) (* i)) j)) (* j)) RWTS : 102 - ANNI : 39 - COMM : 1 diff --git a/tests/snapshots/run@tests::programs::stress_tests::apelacion.snap b/tests/snapshots/run@tests::programs::stress_tests::apelacion.snap index ffc33c61..7dc19a0a 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::apelacion.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::apelacion.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/apelacion.hvm --- -#31999968000000 +12171264 RWTS : 1_524_001_905 - ANNI : 635_000_952 - COMM : 254_000_063 diff --git a/tests/snapshots/run@tests::programs::stress_tests::fib_rec.snap b/tests/snapshots/run@tests::programs::stress_tests::fib_rec.snap index 61b0abcb..4ab7138d 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::fib_rec.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::fib_rec.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/fib_rec.hvm --- -#1346269 +1346269 RWTS : 39_284_572 - ANNI : 18_137_111 - COMM : 2_178_308 diff --git a/tests/snapshots/run@tests::programs::stress_tests::sum_rec.snap b/tests/snapshots/run@tests::programs::stress_tests::sum_rec.snap index a0208e4c..3d70f8a8 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::sum_rec.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::sum_rec.snap @@ -3,10 +3,10 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_rec.hvm --- -#67108864 -RWTS : 1_275_068_405 -- ANNI : 603_979_770 -- COMM : 67_108_863 -- ERAS : 134_217_727 -- DREF : 268_435_455 -- OPER : 201_326_590 +8388608 +RWTS : 159_383_541 +- ANNI : 75_497_466 +- COMM : 8_388_607 +- ERAS : 16_777_215 +- DREF : 33_554_431 +- OPER : 25_165_822 diff --git a/tests/snapshots/run@tests::programs::stress_tests::sum_tail.snap b/tests/snapshots/run@tests::programs::stress_tests::sum_tail.snap index c741bc28..90ccb158 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::sum_tail.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::sum_tail.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_tail.hvm --- -#49999995000000 +15783104 RWTS : 120_000_009 - ANNI : 50_000_004 - COMM : 20_000_000 diff --git a/tests/snapshots/run@tests::programs::stress_tests::sum_tree.snap b/tests/snapshots/run@tests::programs::stress_tests::sum_tree.snap index b154b122..6ff8a478 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::sum_tree.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::sum_tree.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/sum_tree.hvm --- -#16777216 +0 RWTS : 771_751_906 - ANNI : 369_098_738 - COMM : 83_886_075 diff --git a/tests/snapshots/run@tests::programs::stress_tests::tuple_rots.snap b/tests/snapshots/run@tests::programs::stress_tests::tuple_rots.snap index 929c9139..1869f17b 100644 --- a/tests/snapshots/run@tests::programs::stress_tests::tuple_rots.snap +++ b/tests/snapshots/run@tests::programs::stress_tests::tuple_rots.snap @@ -3,7 +3,7 @@ source: tests/tests.rs expression: output input_file: tests/programs/stress_tests/tuple_rots.hvm --- -((#1 (#2 (#3 (#4 (#5 (#6 (#7 (#8 a)))))))) a) +((1 (2 (3 (4 (5 (6 (7 (8 a)))))))) a) RWTS : 64_000_038 - ANNI : 48_000_013 - COMM : 2_000_000 diff --git a/tests/snapshots/run@tests::programs::u24.snap b/tests/snapshots/run@tests::programs::u24.snap new file mode 100644 index 00000000..e3115c02 --- /dev/null +++ b/tests/snapshots/run@tests::programs::u24.snap @@ -0,0 +1,12 @@ +--- +source: tests/tests.rs +expression: output +input_file: tests/programs/u24.hvm +--- +{12 {8 {20 {5 {0 {0 {1 {0 {1 {2 {10 {8 {40 {2 {16777215 {0 {3 *}}}}}}}}}}}}}}}}} +RWTS : 108 +- ANNI : 17 +- COMM : 1 +- ERAS : 18 +- DREF : 55 +- OPER : 17 diff --git a/tests/transform.rs b/tests/transform.rs index 654715ca..f447bb9d 100644 --- a/tests/transform.rs +++ b/tests/transform.rs @@ -55,16 +55,16 @@ pub fn test_eta() { } assert_snapshot!(parse_and_reduce("((x y) (x y))"), @"(x x)"); assert_snapshot!(parse_and_reduce("((a (b (c (d (e f))))) (a (b (c (d (e f))))))"), @"(a a)"); - assert_snapshot!(parse_and_reduce("<+ (a b) (a b)>"), @"<+ a a>"); + assert_snapshot!(parse_and_reduce("$((a b) (a b))"), @"$(a a)"); assert_snapshot!(parse_and_reduce("(a b) & ((a b) (c d)) ~ (c d) "), @r###" a & (a c) ~ c "###); - assert_snapshot!(parse_and_reduce("((a b) [a b])"), @"((a b) [a b])"); + assert_snapshot!(parse_and_reduce("((a b) {a b})"), @"((a b) {a b})"); assert_snapshot!(parse_and_reduce("((a (b c)) (b c))"), @"((a b) b)"); - assert_snapshot!(parse_and_reduce("([(a b) (c d)] [(a b) (c d)])"), @"(a a)"); + assert_snapshot!(parse_and_reduce("({(a b) (c d)} {(a b) (c d)})"), @"(a a)"); assert_snapshot!(parse_and_reduce("(* *)"), @"*"); - assert_snapshot!(parse_and_reduce("([(#0 #0) (#12345 #12345)] [(* *) (a a)])"), @"([#0 #12345] [* (a a)])"); + assert_snapshot!(parse_and_reduce("({(0 0) (12345 12345)} {(* *) (a a)})"), @"({0 12345} {* (a a)})"); } #[test] @@ -75,7 +75,7 @@ pub fn test_inline() { } assert_snapshot!(parse_and_inline(" @era = * - @num = #123 + @num = 123 @abab = (a (b (a b))) @ref = @abab @def = @ref @@ -99,9 +99,9 @@ pub fn test_inline() { @foo = @unbound - @into = (* (#123 (@abab (@abab (@abab (@abab (@into (@unbound (@unbound (@unbound @unbound)))))))))) + @into = (* (123 (@abab (@abab (@abab (@abab (@into (@unbound (@unbound (@unbound @unbound)))))))))) - @num = #123 + @num = 123 @ref = @abab "###); diff --git a/transform/Cargo.toml b/transform/Cargo.toml index 54692452..e4b2dfbc 100644 --- a/transform/Cargo.toml +++ b/transform/Cargo.toml @@ -13,10 +13,17 @@ hvm64-util = { path = "../util", default-features = false } hvm64-runtime = { path = "../runtime", default-features = false } hvm64-ast = { path = "../ast", default-features = false } hvm64-host = { path = "../host", default-features = false } +hvm64-num = { path = "../num", default-features = false } [features] default = ["std"] -std = ["hvm64-util/std", "hvm64-runtime/std", "hvm64-ast/std", "hvm64-host/std"] +std = [ + "hvm64-util/std", + "hvm64-runtime/std", + "hvm64-ast/std", + "hvm64-host/std", + "hvm64-num/std", +] [lints] workspace = true diff --git a/transform/src/eta_reduce.rs b/transform/src/eta_reduce.rs index 51b70f12..6d8907d4 100644 --- a/transform/src/eta_reduce.rs +++ b/transform/src/eta_reduce.rs @@ -58,8 +58,7 @@ use hvm64_util::prelude::*; use core::ops::RangeFrom; use hvm64_ast::{Net, Tree}; - -use ordered_float::OrderedFloat; +use hvm64_num::Num; pub trait EtaReduce { fn eta_reduce(&mut self); @@ -83,8 +82,7 @@ impl EtaReduce for Net { enum NodeType { Ctr(u16), Var(isize), - Int(i64), - F32(OrderedFloat), + Num(Num), Era, Other, Hole, @@ -99,24 +97,23 @@ struct Phase1<'a> { impl<'a> Phase1<'a> { fn walk_tree(&mut self, tree: &'a Tree) { match tree { - Tree::Ctr { lab, lft, rgt } => { + Tree::Ctr { lab, p1, p2 } => { self.nodes.push(NodeType::Ctr(*lab)); - self.walk_tree(lft); - self.walk_tree(rgt); + self.walk_tree(p1); + self.walk_tree(p2); } - Tree::Var { nam } => { - if let Some(i) = self.vars.get(&**nam) { + Tree::Var(name) => { + if let Some(i) = self.vars.get(&**name) { let j = self.nodes.len() as isize; self.nodes.push(NodeType::Var(*i as isize - j)); self.nodes[*i] = NodeType::Var(j - *i as isize); } else { - self.vars.insert(nam, self.nodes.len()); + self.vars.insert(name, self.nodes.len()); self.nodes.push(NodeType::Hole); } } Tree::Era => self.nodes.push(NodeType::Era), - Tree::Int { val } => self.nodes.push(NodeType::Int(*val)), - Tree::F32 { val } => self.nodes.push(NodeType::F32(*val)), + Tree::Num(num) => self.nodes.push(NodeType::Num(*num)), _ => { self.nodes.push(NodeType::Other); for i in tree.children() { @@ -136,17 +133,17 @@ impl Phase2 { fn reduce_tree(&mut self, tree: &mut Tree) -> NodeType { let index = self.index.next().unwrap(); let ty = self.nodes[index]; - if let Tree::Ctr { lft, rgt, .. } = tree { - let a = self.reduce_tree(lft); - let b = self.reduce_tree(rgt); + if let Tree::Ctr { p1, p2, .. } = tree { + let a = self.reduce_tree(p1); + let b = self.reduce_tree(p2); if a == b { let reducible = match a { NodeType::Var(delta) => self.nodes[index.wrapping_add_signed(delta)] == ty, - NodeType::Era | NodeType::Int(_) | NodeType::F32(_) => true, + NodeType::Era | NodeType::Num(_) => true, _ => false, }; if reducible { - *tree = mem::take(lft); + *tree = mem::take(p1); return a; } } diff --git a/transform/src/inline.rs b/transform/src/inline.rs index 95a7462c..24f959c6 100644 --- a/transform/src/inline.rs +++ b/transform/src/inline.rs @@ -43,19 +43,19 @@ impl InlineState { let mut tortoise = &net.root; // Whether or not the tortoise should take a step let mut parity = false; - while let Tree::Ref { nam } = hare { - let Some(net) = &book.nets.get(nam) else { break }; + while let Tree::Ref(name) = hare { + let Some(net) = &book.nets.get(name) else { break }; if net.should_inline() { hare = &net.root; } else { break; } if parity { - let Tree::Ref { nam: tortoise_nam } = tortoise else { unreachable!() }; - if tortoise_nam == nam { - Err(TransformError::InfiniteRefCycle(nam.to_owned()))?; + let Tree::Ref(tortoise_name) = tortoise else { unreachable!() }; + if tortoise_name == name { + Err(TransformError::InfiniteRefCycle(name.to_owned()))?; } - tortoise = &book.nets[tortoise_nam].root; + tortoise = &book.nets[tortoise_name].root; } parity = !parity; } @@ -66,10 +66,10 @@ impl InlineState { } fn inline_into(&self, tree: &mut Tree) -> bool { maybe_grow(|| { - let Tree::Ref { nam } = &*tree else { + let Tree::Ref(name) = &*tree else { return tree.children_mut().map(|t| self.inline_into(t)).fold(false, bool::bitor); }; - if let Some(inlined) = self.inlinees.get(nam) { + if let Some(inlined) = self.inlinees.get(name) { *tree = inlined.clone(); true } else { diff --git a/transform/src/pre_reduce.rs b/transform/src/pre_reduce.rs index 7d25d5a4..20c91fcd 100644 --- a/transform/src/pre_reduce.rs +++ b/transform/src/pre_reduce.rs @@ -53,19 +53,19 @@ impl PreReduce for Book { rewrites: Rewrites::default(), }; - for nam in self.nets.keys() { - state.pre_reduce(nam) + for name in self.nets.keys() { + state.pre_reduce(name) } let State { seen, rewrites, .. } = state; let mut not_normal = vec![]; - for (nam, state) in seen { + for (name, state) in seen { if let SeenState::Reduced { net, normal } = state { if !normal { - not_normal.push(nam.clone()); + not_normal.push(name.clone()); } - self.nets.insert(nam, net); + self.nets.insert(name, net); } } @@ -120,8 +120,8 @@ struct State<'a> { impl<'a> State<'a> { fn visit_tree(&mut self, tree: &Tree) { maybe_grow(move || { - if let Tree::Ref { nam } = tree { - self.pre_reduce(nam); + if let Tree::Ref(name) = tree { + self.pre_reduce(name); } tree.children().for_each(|child| self.visit_tree(child)) }) @@ -133,17 +133,17 @@ impl<'a> State<'a> { self.visit_tree(b); } } - fn pre_reduce(&mut self, nam: &str) { - if self.seen.contains_key(nam) || (self.skip)(nam) || self.book.get(nam).is_none() { + fn pre_reduce(&mut self, name: &str) { + if self.seen.contains_key(name) || (self.skip)(name) || self.book.get(name).is_none() { return; } - self.seen.insert(nam.to_owned(), SeenState::Cycled); + self.seen.insert(name.to_owned(), SeenState::Cycled); // First, pre-reduce all nets referenced by this net by walking the tree - self.visit_net(self.book.get(nam).unwrap()); + self.visit_net(self.book.get(name).unwrap()); let mut rt = hvm64_runtime::Net::new(self.area); - rt.boot(self.host.defs.get(nam).expect("No function.")); + rt.boot(self.host.defs.get(name).expect("No function.")); let n_reduced = rt.reduce(self.max_rwts as usize); self.rewrites += rt.rwts; @@ -157,9 +157,9 @@ impl<'a> State<'a> { // Mutate the host in-place with the pre-reduced net. let instr = self.host.encode_def(&net); - self.host.get_mut::(nam).data = instr; + self.host.get_mut::(name).data = instr; // Replace the "Cycled" state with the "Reduced" state - *self.seen.get_mut(nam).unwrap() = SeenState::Reduced { net, normal: n_reduced.is_some() }; + *self.seen.get_mut(name).unwrap() = SeenState::Reduced { net, normal: n_reduced.is_some() }; } } diff --git a/transform/src/prune.rs b/transform/src/prune.rs index e1e0dd8d..ea2b19e7 100644 --- a/transform/src/prune.rs +++ b/transform/src/prune.rs @@ -36,8 +36,8 @@ impl<'a> PruneState<'a> { } fn visit_tree(&mut self, tree: &Tree) { maybe_grow(|| { - if let Tree::Ref { nam } = tree { - self.visit_def(nam); + if let Tree::Ref(name) = tree { + self.visit_def(name); } else { tree.children().for_each(|t| self.visit_tree(t)); } diff --git a/util/src/bi_enum.rs b/util/src/bi_enum.rs index 65ab1f1f..005030a3 100644 --- a/util/src/bi_enum.rs +++ b/util/src/bi_enum.rs @@ -19,12 +19,14 @@ macro_rules! bi_enum { impl $Ty { #[allow(unused)] + #[inline(always)] pub unsafe fn from_unchecked(value: $uN) -> $Ty { Self::try_from(value).unwrap_unchecked() } } impl From<$Ty> for $uN { + #[inline(always)] fn from(value: $Ty) -> Self { value as Self } } }; @@ -37,9 +39,23 @@ macro_rules! bi_enum { ) => { bi_enum! { #[repr($uN)] $(#$attr)* $vis enum $Ty { $($(#$var_addr)* $Variant = $value,)* } } + #[allow(unused)] + impl $Ty { + #[inline] + pub fn from_str_prefix(str: &str) -> Option { + $(if str.starts_with($str) { Some($Ty::$Variant) } else)* + { None } + } + + #[inline] + pub fn as_str(self) -> &'static str { + match self { $($Ty::$Variant => $str,)* } + } + } + impl core::fmt::Display for $Ty { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - f.write_str(match self { $($Ty::$Variant => $str,)* }) + f.write_str(self.as_str()) } } diff --git a/util/src/lib.rs b/util/src/lib.rs index db27903a..9edc5d09 100644 --- a/util/src/lib.rs +++ b/util/src/lib.rs @@ -2,8 +2,6 @@ pub mod prelude; -pub mod ops; - mod bi_enum; mod deref; mod multi_iterator; diff --git a/util/src/ops.rs b/util/src/ops.rs deleted file mode 100644 index fc77c475..00000000 --- a/util/src/ops.rs +++ /dev/null @@ -1,245 +0,0 @@ -mod num; -mod word; - -use crate::prelude::*; - -use crate::bi_enum; - -use self::{ - num::Numeric, - word::{FromWord, ToWord}, -}; -use core::{ - cmp::{Eq, Ord}, - str::FromStr, -}; - -bi_enum! { - #[repr(u8)] - /// The type of a numeric operation. - /// - /// This dictates how the bits of the operands will be interpreted, - /// and the return type of the operation. - #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - pub enum Ty { - "u8": U8 = 0, - "u16": U16 = 1, - "u32": U32 = 2, - "u60": U60 = 3, - "i8": I8 = 4, - "i16": I16 = 5, - "i32": I32 = 6, - "f32": F32 = 7, - } -} - -impl Ty { - #[inline(always)] - fn is_int(&self) -> bool { - *self < Self::F32 - } -} - -bi_enum! { - #[repr(u8)] - /// Native operations on numerics (u8, u16, u32, u60, i8, i16, i32, f32). - /// - /// Each operation has a swapped counterpart (accessible with `.swap()`), - /// where the order of the operands is swapped. - /// - /// Operations without an already-named counterpart (e.g. `Add <-> Add` and - /// `Lt <-> Gt`) are suffixed with `$`/`S`: `(-$ 1 2) = (- 2 1) = 1`. - #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] - pub enum Op { - "+": Add = 0, - "-": Sub = 1, - "-$": SubS = 2, - "*": Mul = 3, - "/": Div = 4, - "/$": DivS = 5, - "%": Rem = 6, - "%$": RemS = 7, - "&": And = 8, - "|": Or = 9, - "^": Xor = 10, - "<<": Shl = 11, - "<<$": ShlS = 12, - ">>": Shr = 13, - ">>$": ShrS = 14, - // operators returning ints should go after `Eq` - "==": Eq = 15, - "!=": Ne = 16, - "<": Lt = 17, - ">": Gt = 18, - "<=": Le = 19, - ">=": Ge = 20, - } -} - -impl Op { - /// Returns this operation's swapped counterpart. - /// - /// For all `op, a, b`, `op.swap().op(a, b) == op.op(b, a)`. - #[inline] - pub fn swap(self) -> Self { - match self { - Self::Add => Self::Add, - Self::Sub => Self::SubS, - Self::SubS => Self::Sub, - Self::Mul => Self::Mul, - Self::Div => Self::DivS, - Self::DivS => Self::Div, - Self::Rem => Self::RemS, - Self::RemS => Self::Rem, - Self::And => Self::And, - Self::Or => Self::Or, - Self::Xor => Self::Xor, - Self::Shl => Self::ShlS, - Self::ShlS => Self::Shl, - Self::Shr => Self::ShrS, - Self::ShrS => Self::Shr, - Self::Eq => Self::Eq, - Self::Ne => Self::Ne, - Self::Lt => Self::Gt, - Self::Gt => Self::Lt, - Self::Le => Self::Ge, - Self::Ge => Self::Le, - } - } - - fn op(self, a: u64, b: u64) -> u64 { - let a = T::from_word(a); - let b = T::from_word(b); - - match self { - Self::Add => T::add(a, b).to_word(), - Self::Sub => T::sub(a, b).to_word(), - Self::SubS => T::sub(b, a).to_word(), - Self::Mul => T::mul(a, b).to_word(), - Self::Div => T::div(a, b).to_word(), - Self::DivS => T::div(b, a).to_word(), - Self::Rem => T::rem(a, b).to_word(), - Self::RemS => T::rem(b, a).to_word(), - Self::And => T::and(a, b).to_word(), - Self::Or => T::or(a, b).to_word(), - Self::Xor => T::xor(a, b).to_word(), - Self::Shl => T::shl(a, b).to_word(), - Self::ShlS => T::shl(b, a).to_word(), - Self::Shr => T::shr(a, b).to_word(), - Self::ShrS => T::shr(b, a).to_word(), - - // comparison operators return an integer, which is not necessarily a `T`. - Self::Eq => (a == b).into(), - Self::Ne => (a != b).into(), - Self::Lt => (a < b).into(), - Self::Le => (a <= b).into(), - Self::Gt => (a > b).into(), - Self::Ge => (a >= b).into(), - } - } - - #[inline(always)] - fn is_comparison(&self) -> bool { - *self >= Self::Eq - } -} - -/// A numeric operator. -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] -#[repr(C, align(2))] -pub struct TypedOp { - /// The type of the operands. - pub ty: Ty, - /// The operation. An opaque type whose interpretation depends on `ty`. - pub op: Op, -} - -impl TypedOp { - pub unsafe fn from_unchecked(val: u16) -> Self { - mem::transmute(val) - } - - /// Whether this operation returns an int. - #[inline(always)] - pub fn is_int(&self) -> bool { - self.ty.is_int() || self.op.is_comparison() - } - - pub fn swap(self) -> Self { - Self { op: self.op.swap(), ty: self.ty } - } - - #[inline] - pub fn op(self, a: u64, b: u64) -> u64 { - const U60: u64 = 0xFFF_FFFF_FFFF_FFFF; - - match self.ty { - Ty::I8 => self.op.op::(a, b), - Ty::I16 => self.op.op::(a, b), - Ty::I32 => self.op.op::(a, b), - - Ty::U8 => self.op.op::(a, b), - Ty::U16 => self.op.op::(a, b), - Ty::U32 => self.op.op::(a, b), - Ty::U60 => self.op.op::(a, b) & U60, - - Ty::F32 => self.op.op::(a, b), - } - } -} - -impl fmt::Display for TypedOp { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.ty { - Ty::U60 => write!(f, "{}", self.op), - _ => write!(f, "{}.{}", self.ty, self.op), - } - } -} - -impl TryFrom for TypedOp { - type Error = (); - - fn try_from(value: u16) -> Result { - let [ty, op] = value.to_ne_bytes(); - - Ok(Self { ty: Ty::try_from(ty)?, op: Op::try_from(op)? }) - } -} - -impl From for u16 { - fn from(TypedOp { ty, op }: TypedOp) -> Self { - u16::from_ne_bytes([ty as u8, op as u8]) - } -} - -#[derive(Debug)] -pub enum OpParseError { - Type(String), - Op(String), -} - -impl fmt::Display for OpParseError { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self { - OpParseError::Type(ty) => write!(f, "invalid type: {ty}"), - OpParseError::Op(op) => write!(f, "invalid operator: {op}"), - } - } -} - -impl FromStr for TypedOp { - type Err = OpParseError; - - fn from_str(s: &str) -> Result { - match s.split('.').collect::>().as_slice() { - [ty, op] => Ok(Self { - ty: Ty::from_str(ty).map_err(|_| OpParseError::Type(ty.to_string()))?, - op: Op::from_str(op).map_err(|_| OpParseError::Op(op.to_string()))?, - }), - [op] => Ok(Self { ty: Ty::U60, op: Op::from_str(op).map_err(|_| OpParseError::Op(op.to_string()))? }), - - _ => Err(OpParseError::Op(s.to_string())), - } - } -}