]> Repositorios git - scryer-prolog.git/commitdiff
correct sort, keysort
authorMark Thom <[email protected]>
Mon, 12 Mar 2018 01:51:25 +0000 (19:51 -0600)
committerMark Thom <[email protected]>
Mon, 12 Mar 2018 01:51:25 +0000 (19:51 -0600)
src/prolog/builtins.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/macros.rs

index 5da939459b9e426eb5150da888de11926d8d48fb..535db0937f3d93355cff32d13548e70aaaf78fff 100644 (file)
@@ -622,7 +622,9 @@ fn get_builtins() -> Code {
          fail!(),
          compare_execute!(), // compare/3, 464.
          is_atom!(temp_v!(1)), // atom/1, 465.
-         proceed!()
+         proceed!(),
+         sort_execute!(), // sort/2, 467.
+         keysort_execute!() // keysort/2, 468.
     ]
 }
 
@@ -736,6 +738,8 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir)
     code_dir.insert((clause_name!("\\=@="), 2), (392, builtin.clone()));
     code_dir.insert((clause_name!("compare"), 3), (464, builtin.clone()));
     code_dir.insert((clause_name!("atom"), 1), (465, builtin.clone()));
+    code_dir.insert((clause_name!("sort"), 2), (467, builtin.clone()));
+    code_dir.insert((clause_name!("keysort"), 2), (468, builtin.clone()));
     
     (code_dir, op_dir)
 }
@@ -794,7 +798,10 @@ pub fn builtin_module() -> Module
                                             (clause_name!("ground"), 1),
                                             (clause_name!("setup_call_cleanup"), 3),
                                             (clause_name!("call_with_inference_limit"), 3),
-                                            (clause_name!("compare"), 3)]);
+                                            (clause_name!("compare"), 3),
+                                            (clause_name!("atom"), 1),
+                                            (clause_name!("sort"), 2),
+                                            (clause_name!("keysort"), 2)]);
 
     for arity in 0 .. 63 {
         module_decl.exports.push((clause_name!("call"), arity));
index 892d8911110116badaa6ea890c03ef8ed42395f4..97adb11d7944af3ede5e53dd368b966fb2ae9f12 100644 (file)
@@ -1633,6 +1633,22 @@ impl MachineState {
         Ok(())
     }
 
+    fn term_dedup(&self, list: &mut Vec<Addr>) {
+        let mut result = vec![];
+
+        for a2 in list.iter().cloned() {
+            if let Some(a1) = result.last().cloned() {
+                if self.compare_term_test(&a1, &a2) == Ordering::Equal {
+                    continue;
+                }
+            }
+
+            result.push(a2);
+        }
+        
+        *list = result;
+    }
+    
     fn to_list<Iter: Iterator<Item=Addr>>(&mut self, values: Iter) -> usize {
         let head_addr = self.heap.h;
 
@@ -2082,6 +2098,8 @@ impl MachineState {
                 });
                                 
                 list.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
+                self.term_dedup(&mut list);
+                
                 let heap_addr = Addr::HeapCell(self.to_list(list.into_iter()));
                 
                 let r2 = self[temp_v!(2)].clone();
@@ -2095,6 +2113,8 @@ impl MachineState {
                 });
                 
                 list.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
+                self.term_dedup(&mut list);
+                
                 let heap_addr = Addr::HeapCell(self.to_list(list.into_iter()));
                 
                 let r2 = self[temp_v!(2)].clone();
@@ -2114,7 +2134,7 @@ impl MachineState {
                     key_pairs.push((key, val.clone()));
                 }
                 
-                key_pairs.sort_unstable_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
+                key_pairs.sort_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
                 
                 let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
                 let heap_addr = Addr::HeapCell(self.to_list(key_pairs));
@@ -2136,7 +2156,7 @@ impl MachineState {
                     key_pairs.push((key, val.clone()));
                 }
                 
-                key_pairs.sort_unstable_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
+                key_pairs.sort_by(|a1, a2| self.compare_term_test(&a1.0, &a2.0));
                 
                 let key_pairs = key_pairs.into_iter().map(|kp| kp.1);
                 let heap_addr = Addr::HeapCell(self.to_list(key_pairs));
index 838340004e2ffb0762a09cdc6c96304463dcb590..c6fed893041006cc44818a18da5663ba9d5e7844 100644 (file)
@@ -719,3 +719,15 @@ macro_rules! keysort_call {
         Line::Control(ControlInstruction::KeySortCall)
     )
 }
+
+macro_rules! sort_execute {
+    () => (
+        Line::Control(ControlInstruction::SortExecute)
+    )
+}
+
+macro_rules! keysort_execute {
+    () => (
+        Line::Control(ControlInstruction::KeySortExecute)
+    )
+}