]> Repositorios git - scryer-prolog.git/commitdiff
Added new unify methods
authorFayeed Pawaskar <[email protected]>
Mon, 4 Sep 2023 08:42:11 +0000 (14:12 +0530)
committerFayeed Pawaskar <[email protected]>
Mon, 4 Sep 2023 08:42:11 +0000 (14:12 +0530)
src/machine/unify.rs

index e73fa4a17892395da5b7f2f3c3740ba0f537b1a0..ed14f296a9215c1f05613a6cfedd37a0e24bc8f4 100644 (file)
@@ -12,6 +12,7 @@ use std::ops::{Deref, DerefMut};
 use derive_deref::*;
 use fxhash::FxBuildHasher;
 use indexmap::IndexSet;
+use num_order::NumOrd;
 
 pub(crate) trait Unifier: DerefMut<Target = MachineState> {
     fn unify_structure(&mut self, s1: usize, value: HeapCellValue) {
@@ -426,8 +427,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
         match Number::try_from(value) {
             Ok(n2) => match n2 {
                 Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {}
-                Number::Integer(n2) if n1.get_num() == *n2 => {}
-                Number::Rational(n2) if n1.get_num() == *n2 => {}
+                Number::Integer(n2) if (*n2).num_eq(&n1.get_num()) => {}
+                Number::Rational(n2) if (*n2).num_eq(&Integer::from(n1.get_num())) => {}
                 _ => {
                     self.fail = true;
                 }
@@ -464,6 +465,48 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
         }
     }
 
+    fn unify_big_integer(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
+        if let Some(r) = value.as_var() {
+            Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
+            return;
+        }
+
+        match Number::try_from(value) {
+            Ok(n2) => match n2 {
+                Number::Fixnum(n2) if (*n1).num_eq(&n2.get_num()) => {}
+                Number::Integer(n2) if (*n1).num_eq(&n2.value()) => {}
+                Number::Rational(n2) if (*n2).num_eq(&n1.value()) => {}
+                _ => {
+                    self.fail = true;
+                }
+            },
+            Err(_) => {
+                self.fail = true;
+            }
+        }
+    }
+
+    fn unify_big_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
+        if let Some(r) = value.as_var() {
+            Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
+            return;
+        }
+
+        match Number::try_from(value) {
+            Ok(n2) => match n2 {
+                Number::Fixnum(n2) if (*n1).num_eq(&Integer::from(n2.get_num())) => {}
+                Number::Integer(n2) if (*n1).num_eq(&n2.value()) => {}
+                Number::Rational(n2) if n1 == n2 => {}
+                _ => {
+                    self.fail = true;
+                }
+            },
+            Err(_) => {
+                self.fail = true;
+            }
+        }
+    }
+
     fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
         if let Some(r) = value.as_var() {
             Self::bind(self, r, HeapCellValue::from(f1));
@@ -489,10 +532,10 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
 
         match_untyped_arena_ptr!(ptr,
              (ArenaHeaderTag::Integer, int_ptr) => {
-                 Self::unify_big_num(self, int_ptr, value);
+                 Self::unify_big_integer(self, int_ptr, value);
              }
              (ArenaHeaderTag::Rational, rat_ptr) => {
-                 Self::unify_big_num(self, rat_ptr, value);
+                 Self::unify_big_rational(self, rat_ptr, value);
              }
              (ArenaHeaderTag::Stream, stream) => {
                  read_heap_cell!(value,