diff --git a/Cargo.toml b/Cargo.toml index ddcf79fd..e7b7f930 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,6 @@ hostname = ["dep:hostname"] tls = ["dep:native-tls"] http = ["dep:warp", "dep:reqwest"] crypto-full = [] -"rust-version-1.80" = [] [build-dependencies] indexmap = "2.3.0" diff --git a/src/lib/clpz.pl b/src/lib/clpz.pl index b14546bc..89019b4f 100644 --- a/src/lib/clpz.pl +++ b/src/lib/clpz.pl @@ -5088,11 +5088,21 @@ run_propagator(pmod(X,Y,Z), MState) --> ; nonvar(Z), nonvar(X) -> ( Z > 0 -> ( X < 0 -> true - ; X >= Z + ; X >= Z, + % due to X = Z+Y*_ and Y > Z + ( X-Z > 0 -> + X-Z > Z + ; true + ) ) ; Z < 0 -> ( X > 0 -> true - ; X =< Z + ; X =< Z, + % due to X = Z+Y*_ and Y < Z + ( X-Z < 0 -> + X-Z < Z + ; true + ) ) ; Z =:= 0 % Multiple solutions so do nothing special. ), @@ -5100,7 +5110,23 @@ run_propagator(pmod(X,Y,Z), MState) --> YU < X, X =< 0 } -> kill(MState), Z =:= X ; { fd_get(Y, _, n(YL), _, _), YL > X, X >= 0 } -> kill(MState), Z =:= X - ; ( Z > 0 -> + ; ( Z > 0, X < 0 -> + { fd_get(Y, YD, YPs), + YMin is Z+1, + YMax is Z-X, + domain_remove_smaller_than(YD, YMin, YD1), + domain_remove_greater_than(YD1, YMax, YD2) }, + fd_put(Y, YD2, YPs) + % queue_goal((Y #> Z, Y #=< Z-X)) + ; Z < 0, X > 0 -> + { fd_get(Y, YD, YPs), + YMax is Z-1, + YMin is Z-X, + domain_remove_greater_than(YD, YMax, YD1), + domain_remove_smaller_than(YD1, YMin, YD2) }, + fd_put(Y, YD2, YPs) + % queue_goal((Y #< Z, Y #>= Z-X)) + ; Z > 0 -> { fd_get(Y, YD, YPs), YMin is Z + 1, domain_remove_smaller_than(YD, YMin, YD1) }, @@ -5112,7 +5138,16 @@ run_propagator(pmod(X,Y,Z), MState) --> domain_remove_greater_than(YD, YMax, YD1) }, fd_put(Y, YD1, YPs) % queue_goal(Y #< Z) - ; true + ; Z =:= 0, + ( X =:= 0 -> + kill(MState) % trivial + ; % only 4 solutions {-abs(X),-1,1,abs(X)} + { YL is -abs(X), YU is abs(X), + fd_get(Y, YD0, YPs), + domain_remove_smaller_than(YD0, YL, YD1), + domain_remove_greater_than(YD1, YU, YD) }, + fd_put(Y, YD, YPs) + ) ) ) ; run_propagator(pmodz(X,Y,Z), MState), diff --git a/src/lib/dcgs.pl b/src/lib/dcgs.pl index 2dc858a4..835e80a5 100644 --- a/src/lib/dcgs.pl +++ b/src/lib/dcgs.pl @@ -12,8 +12,8 @@ to learn more about them. [op(1105, xfy, '|'), phrase/2, phrase/3, - phrase/4, - phrase/5, + phrase//2, + phrase//3, seq//1, seqq//1, ... //0, @@ -29,9 +29,9 @@ to learn more about them. :- meta_predicate phrase(2, ?, ?). -:- meta_predicate phrase(2, ?, ?, ?). +:- meta_predicate(phrase(3, ?, ?, ?)). -:- meta_predicate phrase(2, ?, ?, ?, ?). +:- meta_predicate(phrase(4, ?, ?, ?, ?)). :- meta_predicate(','(2, 2, ?, ?)). diff --git a/src/lib/ops_and_meta_predicates.pl b/src/lib/ops_and_meta_predicates.pl index 8f904d63..8ffdfb03 100644 --- a/src/lib/ops_and_meta_predicates.pl +++ b/src/lib/ops_and_meta_predicates.pl @@ -26,7 +26,6 @@ :- op(200, xfy, ^). :- op(500, yfx, /\). :- op(500, yfx, \/). -:- op(500, yfx, xor). :- op(400, yfx, div). :- op(400, yfx, //). :- op(400, yfx, rdiv). diff --git a/src/machine/mod.rs b/src/machine/mod.rs index da2ab6df..d180f02d 100644 --- a/src/machine/mod.rs +++ b/src/machine/mod.rs @@ -118,32 +118,6 @@ fn current_dir() -> PathBuf { } } -#[cfg(not(feature = "rust-version-1.80"))] -mod libraries { - use indexmap::IndexMap; - use std::sync::OnceLock; - - fn libraries() -> &'static IndexMap<&'static str, &'static str> { - static LIBRARIES: OnceLock> = OnceLock::new(); - LIBRARIES.get_or_init(|| { - let mut m = IndexMap::new(); - - include!(concat!(env!("OUT_DIR"), "/libraries.rs")); - - m - }) - } - - pub(crate) fn contains(name: &str) -> bool { - libraries().contains_key(name) - } - - pub(crate) fn get(name: &str) -> Option<&'static str> { - libraries().get(name).copied() - } -} - -#[cfg(feature = "rust-version-1.80")] mod libraries { use indexmap::IndexMap; use std::sync::LazyLock; diff --git a/src/machine/system_calls.rs b/src/machine/system_calls.rs index dc5da32a..cc39cba5 100644 --- a/src/machine/system_calls.rs +++ b/src/machine/system_calls.rs @@ -911,27 +911,16 @@ impl MachineState { use crate::parser::lexer::*; let nx = self.store(self.deref(self.registers[2])); - let add_dot = !string.ends_with('.'); - let cursor = std::io::Cursor::new(string); - - let iter = std::io::Read::chain(cursor, { - let mut dot_buf: [u8; '.'.len_utf8()] = [0u8]; - - if add_dot { - '.'.encode_utf8(&mut dot_buf); - } - - std::io::Cursor::new(dot_buf) - }); + let iter = std::io::Cursor::new(string); let mut lexer = Lexer::new(CharReader::new(iter), self); let mut tokens = vec![]; - match lexer.next_token() { + match lexer.next_number_token() { Ok(token @ Token::Literal(Literal::Atom(atom!("-")) | Literal::Char('-'))) => { tokens.push(token); - if let Ok(token) = lexer.next_token() { + if let Ok(token) = lexer.next_number_token() { tokens.push(token); } } @@ -979,9 +968,6 @@ impl MachineState { break; } - Ok('.') => { - lexer.skip_char('.'); - } Ok(c) => { let (line_num, col_num) = (lexer.line_num, lexer.col_num); diff --git a/src/parser/ast.rs b/src/parser/ast.rs index 06c1ab9e..9a400c36 100644 --- a/src/parser/ast.rs +++ b/src/parser/ast.rs @@ -432,6 +432,7 @@ pub enum ParserError { BackQuotedString(usize, usize), IO(IOError), IncompleteReduction(usize, usize), + InfiniteFloat(usize, usize), InvalidSingleQuotedCharacter(char), LexicalError(lexical::Error), MissingQuote(usize, usize), @@ -447,6 +448,7 @@ impl ParserError { match self { &ParserError::BackQuotedString(line_num, col_num) | &ParserError::IncompleteReduction(line_num, col_num) + | &ParserError::InfiniteFloat(line_num, col_num) | &ParserError::MissingQuote(line_num, col_num) | &ParserError::NonPrologChar(line_num, col_num) | &ParserError::ParseBigInt(line_num, col_num) @@ -463,6 +465,9 @@ impl ParserError { ParserError::InvalidSingleQuotedCharacter(..) => { atom!("invalid_single_quoted_character") } + ParserError::InfiniteFloat(..) => { + atom!("infinite_float") + } ParserError::IO(e) if e.kind() == ErrorKind::UnexpectedEof => { atom!("unexpected_end_of_file") } diff --git a/src/parser/lexer.rs b/src/parser/lexer.rs index 06f8a326..75700f38 100644 --- a/src/parser/lexer.rs +++ b/src/parser/lexer.rs @@ -1,3 +1,5 @@ +use crate::arena::F64Ptr; +use crate::arena::TypedArenaPtr; use crate::atom_table::*; pub use crate::machine::machine_state::*; use crate::parser::ast::*; @@ -49,6 +51,55 @@ impl Token { } } +#[derive(Debug)] +enum Number { + BigInt(TypedArenaPtr), + Fixnum(Fixnum), + Float(F64Ptr), +} + +impl Number { + #[inline] + fn to_literal(self) -> Literal { + match self { + Number::BigInt(ibig) => Literal::Integer(ibig), + Number::Fixnum(fixnum) => Literal::Fixnum(fixnum), + Number::Float(f) => Literal::Float(f.as_offset()), + } + } +} + +#[derive(Debug)] +enum NumberToken { + Number(Number), + Partial(String), +} + +impl NumberToken { + #[inline] + fn to_token(self) -> Option { + match self { + NumberToken::Number(number) => Some(Token::Literal(number.to_literal())), + NumberToken::Partial(_) => None, + } + } +} + +macro_rules! try_nt { + ($token:expr, $e: expr) => {{ + match $e { + Ok(c) => c, + Err(e) => { + return if e.is_unexpected_eof() { + Ok(NumberToken::Partial($token)) + } else { + Err(e) + } + } + } + }}; +} + pub struct Lexer<'a, R> { pub(crate) reader: R, pub(crate) machine_st: &'a mut MachineState, @@ -443,7 +494,7 @@ impl<'a, R: CharRead> Lexer<'a, R> { } } - fn hexadecimal_constant(&mut self, start: char) -> Result { + fn hexadecimal_constant(&mut self, start: char) -> Result { self.skip_char(start); let mut c = self.lookahead_char()?; @@ -454,31 +505,21 @@ impl<'a, R: CharRead> Lexer<'a, R> { if hexadecimal_digit_char!(c) { self.skip_char(c); token.push(c); - c = self.lookahead_char()?; + c = try_nt!(token, self.lookahead_char()); } else { break; } } - i64::from_str_radix(&token, 16) - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - Integer::from_str_radix(&token, 16) - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer_by_radix(&token, 16) + .map(NumberToken::Number) } else { self.return_char(start); Err(ParserError::ParseBigInt(self.line_num, self.col_num)) } } - fn octal_constant(&mut self, start: char) -> Result { + fn octal_constant(&mut self, start: char) -> Result { self.skip_char(start); let mut c = self.lookahead_char()?; @@ -489,31 +530,21 @@ impl<'a, R: CharRead> Lexer<'a, R> { if octal_digit_char!(c) { self.skip_char(c); token.push(c); - c = self.lookahead_char()?; + c = try_nt!(token, self.lookahead_char()); } else { break; } } - i64::from_str_radix(&token, 8) - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - Integer::from_str_radix(&token, 8) - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer_by_radix(&token, 8) + .map(NumberToken::Number) } else { self.return_char(start); Err(ParserError::ParseBigInt(self.line_num, self.col_num)) } } - fn binary_constant(&mut self, start: char) -> Result { + fn binary_constant(&mut self, start: char) -> Result { self.skip_char(start); let mut c = self.lookahead_char()?; @@ -524,24 +555,14 @@ impl<'a, R: CharRead> Lexer<'a, R> { if binary_digit_char!(c) { self.skip_char(c); token.push(c); - c = self.lookahead_char()?; + c = try_nt!(token, self.lookahead_char()); } else { break; } } - i64::from_str_radix(&token, 2) - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - Integer::from_str_radix(&token, 2) - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer_by_radix(&token, 2) + .map(NumberToken::Number) } else { self.return_char(start); Err(ParserError::ParseBigInt(self.line_num, self.col_num)) @@ -634,15 +655,10 @@ impl<'a, R: CharRead> Lexer<'a, R> { } } - fn vacate_with_float(&mut self, mut token: String) -> Result { + fn vacate_with_float(&mut self, mut token: String) -> Result { self.return_char(token.pop().unwrap()); - let n = parse_float_lossy(&token)?; - - Ok(Token::Literal(Literal::from(float_alloc!( - n, - self.machine_st.arena - )))) + Ok(Number::Float(float_alloc!(n, self.machine_st.arena))) } fn skip_underscore_in_number(&mut self) -> Result { @@ -663,17 +679,43 @@ impl<'a, R: CharRead> Lexer<'a, R> { } } - pub fn number_token(&mut self, leading_c: char) -> Result { + fn parse_integer_by_radix( + &mut self, + token: &String, + radix: u32, + ) -> Result { + i64::from_str_radix(&token, radix) + .map(|n| { + Fixnum::build_with_checked(n) + .map(Number::Fixnum) + .unwrap_or_else(|_| { + Number::BigInt(arena_alloc!(Integer::from(n), &mut self.machine_st.arena)) + }) + }) + .or_else(|_| { + token + .parse::() + .map(|n| Number::BigInt(arena_alloc!(n, &mut self.machine_st.arena))) + .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) + }) + } + + #[inline] + fn parse_integer(&mut self, token: &String) -> Result { + self.parse_integer_by_radix(token, 10) + } + + fn number_token(&mut self, leading_c: char) -> Result { let mut token = String::with_capacity(16); self.skip_char(leading_c); token.push(leading_c); - let mut c = self.skip_underscore_in_number()?; + let mut c = try_nt!(token, self.skip_underscore_in_number()); while decimal_digit_char!(c) { token.push(c); self.skip_char(c); - c = self.skip_underscore_in_number()?; + c = try_nt!(token, self.skip_underscore_in_number()); } if decimal_point_char!(c) { @@ -681,31 +723,17 @@ impl<'a, R: CharRead> Lexer<'a, R> { if self.reader.peek_char().is_none() { self.return_char('.'); - - token - .parse::() - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer(&token).map(NumberToken::Number) } else if decimal_digit_char!(self.lookahead_char()?) { token.push('.'); token.push(self.read_char()?); - let mut c = self.lookahead_char()?; + let mut c = try_nt!(token, self.lookahead_char()); while decimal_digit_char!(c) { token.push(c); self.skip_char(c); - c = self.lookahead_char()?; + c = try_nt!(token, self.lookahead_char()); } if exponent_char!(c) { @@ -713,12 +741,12 @@ impl<'a, R: CharRead> Lexer<'a, R> { token.push(c); let c = match self.lookahead_char() { - Err(_) => return self.vacate_with_float(token), + Err(_) => return self.vacate_with_float(token).map(NumberToken::Number), Ok(c) => c, }; if !sign_char!(c) && !decimal_digit_char!(c) { - return self.vacate_with_float(token); + return self.vacate_with_float(token).map(NumberToken::Number); } if sign_char!(c) { @@ -728,14 +756,14 @@ impl<'a, R: CharRead> Lexer<'a, R> { let c = match self.lookahead_char() { Err(_) => { self.return_char(token.pop().unwrap()); - return self.vacate_with_float(token); + return self.vacate_with_float(token).map(NumberToken::Number); } Ok(c) => c, }; if !decimal_digit_char!(c) { self.return_char(token.pop().unwrap()); - return self.vacate_with_float(token); + return self.vacate_with_float(token).map(NumberToken::Number); } } @@ -746,7 +774,7 @@ impl<'a, R: CharRead> Lexer<'a, R> { token.push(c); loop { - c = self.lookahead_char()?; + c = try_nt!(token, self.lookahead_char()); if decimal_digit_char!(c) { self.skip_char(c); @@ -757,60 +785,29 @@ impl<'a, R: CharRead> Lexer<'a, R> { } let n = parse_float_lossy(&token)?; - Ok(Token::Literal(Literal::from(float_alloc!( + Ok(NumberToken::Number(Number::Float(float_alloc!( n, self.machine_st.arena )))) } else { - return self.vacate_with_float(token); + return self.vacate_with_float(token).map(NumberToken::Number); } } else { let n = parse_float_lossy(&token)?; - Ok(Token::Literal(Literal::from(float_alloc!( + Ok(NumberToken::Number(Number::Float(float_alloc!( n, self.machine_st.arena )))) } } else { self.return_char('.'); - - token - .parse::() - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer(&token).map(NumberToken::Number) } } else if token.starts_with('0') && token.len() == 1 { if c == 'x' { self.hexadecimal_constant(c).or_else(|e| { if let ParserError::ParseBigInt(..) = e { - token - .parse::() - .map(|n| { - Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)) - }) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| { - ParserError::ParseBigInt(self.line_num, self.col_num) - }) - }) + self.parse_integer(&token).map(NumberToken::Number) } else { Err(e) } @@ -818,24 +815,7 @@ impl<'a, R: CharRead> Lexer<'a, R> { } else if c == 'o' { self.octal_constant(c).or_else(|e| { if let ParserError::ParseBigInt(..) = e { - token - .parse::() - .map(|n| { - Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)) - }) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| { - ParserError::ParseBigInt(self.line_num, self.col_num) - }) - }) + self.parse_integer(&token).map(NumberToken::Number) } else { Err(e) } @@ -843,24 +823,7 @@ impl<'a, R: CharRead> Lexer<'a, R> { } else if c == 'b' { self.binary_constant(c).or_else(|e| { if let ParserError::ParseBigInt(..) = e { - token - .parse::() - .map(|n| { - Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)) - }) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| { - ParserError::ParseBigInt(self.line_num, self.col_num) - }) - }) + self.parse_integer(&token).map(NumberToken::Number) } else { Err(e) } @@ -877,14 +840,14 @@ impl<'a, R: CharRead> Lexer<'a, R> { self.skip_char(c); self.return_char('\''); - return Ok(Token::Literal(Literal::Fixnum(Fixnum::build_with(0)))); + return Ok(NumberToken::Number(Number::Fixnum(Fixnum::build_with(0)))); } else { self.return_char('\\'); } } self.get_single_quoted_char() - .map(|c| Token::Literal(Literal::Fixnum(Fixnum::build_with(c as i64)))) + .map(|c| NumberToken::Number(Number::Fixnum(Fixnum::build_with(c as i64)))) .or_else(|err| { match err { ParserError::UnexpectedChar('\'', ..) => {} @@ -892,57 +855,13 @@ impl<'a, R: CharRead> Lexer<'a, R> { } self.return_char(c); - - token - .parse::() - .map(|n| { - Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)) - }) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| { - ParserError::ParseBigInt(self.line_num, self.col_num) - }) - }) + self.parse_integer(&token).map(NumberToken::Number) }) } else { - token - .parse::() - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer(&token).map(NumberToken::Number) } } else { - token - .parse::() - .map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))) - .or_else(|_| { - token - .parse::() - .map(|n| { - Token::Literal(Literal::Integer(arena_alloc!( - n, - &mut self.machine_st.arena - ))) - }) - .map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num)) - }) + self.parse_integer(&token).map(NumberToken::Number) } } @@ -1001,6 +920,29 @@ impl<'a, R: CharRead> Lexer<'a, R> { } } + pub fn next_number_token(&mut self) -> Result { + self.scan_for_layout()?; + let c = self.lookahead_char()?; + + if !decimal_digit_char!(c) { + return self.name_token(c); + } + + match self.number_token(c) { + Ok(NumberToken::Partial(token_string)) => match self.parse_integer(&token_string) { + Ok(n) => Ok(Token::Literal(n.to_literal())), + Err(_) => { + let n = parse_float_lossy(&token_string)?; + Ok(Token::Literal(Literal::Float( + float_alloc!(n, self.machine_st.arena).as_offset(), + ))) + } + }, + Ok(NumberToken::Number(n)) => return Ok(Token::Literal(n.to_literal())), + Err(e) => return Err(e), + } + } + pub fn next_token(&mut self) -> Result { let layout_inserted = self.scan_for_layout()?; let cr = self.lookahead_char(); @@ -1053,7 +995,10 @@ impl<'a, R: CharRead> Lexer<'a, R> { } if decimal_digit_char!(c) { - return self.number_token(c); + return self.number_token(c).and_then(|nt| match nt.to_token() { + Some(token) => Ok(token), + None => Err(ParserError::unexpected_eof()), + }); } if c == ']' { diff --git a/src/parser/parser.rs b/src/parser/parser.rs index eee22294..dd7b007b 100644 --- a/src/parser/parser.rs +++ b/src/parser/parser.rs @@ -976,11 +976,17 @@ impl<'a, R: CharRead> Parser<'a, R> { Token::Literal(Literal::Rational(n)) => { self.negate_number(n, negate_rat_rc, |r, _| Literal::Rational(r)) } - Token::Literal(Literal::Float(n)) => self.negate_number( + Token::Literal(Literal::Float(n)) if F64Ptr::from_offset(n).is_infinite() => { + return Err(ParserError::InfiniteFloat( + self.lexer.line_num, + self.lexer.col_num, + )); + } + Token::Literal(Literal::Float(n)) => self.negate_number( **n.as_ptr(), |n, _| -n, |n, arena| Literal::from(float_alloc!(n, arena)), - ), + ), Token::Literal(c) => { let atomized = atomize_constant(&self.lexer.machine_st.atom_tbl, c); diff --git a/src/tests/arithmetic.pl b/src/tests/arithmetic.pl index 2e4872d4..eea4b3ac 100644 --- a/src/tests/arithmetic.pl +++ b/src/tests/arithmetic.pl @@ -258,14 +258,14 @@ test_and_or_xor(X, Y, AndExpected, OrExpected, XorExpected) :- Or2 is Y \/ X, Or == OrExpected, Or == Or2, - Xor is X xor Y, - Xor2 is Y xor X, + Xor is xor(X, Y), + Xor2 is xor(Y, X), Xor == XorExpected, Xor2 == Xor, call(is, And3, X /\ Y), call(is, Or3, X \/ Y), - call(is, Xor3, X xor Y), + call(is, Xor3, xor(X, Y)), And3 == And, Or3 == Or, Xor3 == Xor. @@ -613,7 +613,7 @@ test("and_or_xor", ( ]), arithmetic_tests:test_and_or_xor(X, Y, AndExpected, OrExpected, XorExpected)), \+ catch(_ is 1 /\ 2.0, _, false), \+ catch(_ is 1 \/ 2.0, _, false), - \+ catch(_ is 1 xor 2.0, _, false) + \+ catch(_ is xor(1, 2.0), _, false) )). test("mod_rem", (