]> Repositorios git - scryer-prolog.git/commitdiff
Remove redundant alias resolution in at_end_of_stream/1, add corresponding tests...
authorEmilie Burgun <[email protected]>
Fri, 7 Feb 2025 13:59:32 +0000 (14:59 +0100)
committerEmilie Burgun <[email protected]>
Fri, 7 Feb 2025 14:05:01 +0000 (15:05 +0100)
Also fixed at_end_of_stream/0 leaving a choicepoint.

src/lib/builtins.pl
src/machine/mod.rs
src/machine/streams.rs

index 745cbc48795f73f2c13800561f7e76b7a14ccb15..f6df8da7561f21bacbaba0cda68b0606ca21736a 100644 (file)
@@ -2188,12 +2188,10 @@ stream_property(S, P) :-
 %% at_end_of_stream(+Stream).
 %
 % True iff the stream Stream has ended
-at_end_of_stream(S_or_a) :-
-    (  var(S_or_a) ->
+at_end_of_stream(S) :-
+    (  var(S) ->
        throw(error(instantiation_error, at_end_of_stream/1))
-    ;  atom(S_or_a) ->
-       stream_property(S, alias(S_or_a))
-    ;  S = S_or_a
+    ;  true
     ),
     stream_property(S, end_of_stream(E)),
     ( E = at -> true ; E = past ).
@@ -2205,7 +2203,7 @@ at_end_of_stream :-
     current_input(S),
     stream_property(S, end_of_stream(E)),
     !,
-    ( E = at ; E = past ).
+    ( E = at -> true ; E = past ).
 
 %% set_stream_position(+Stream, +Position).
 %
index 1072403008dd6b289250a39769222da67bcf09e7..e2306283b5f7e2bd904262fc58864efa6b4aab0e 100644 (file)
@@ -510,9 +510,12 @@ impl Machine {
 
         self.indices.streams.insert(self.user_error);
 
+        let mut null_options = StreamOptions::default();
+        null_options.set_alias_to_atom_opt(Some(atom!("null_stream")));
+
         self.indices
             .stream_aliases
-            .insert(atom!("null_stream"), Stream::Null(StreamOptions::default()));
+            .insert(atom!("null_stream"), Stream::Null(null_options));
     }
 
     #[inline(always)]
index 253bd47ea7762383692b9b6474dcd0e9bb715f4d..54efbd39cb065e185d8e737bd2a453acc85f2b16 100644 (file)
@@ -1908,6 +1908,14 @@ impl MachineState {
 mod test {
     use super::*;
     use crate::machine::config::*;
+    use crate::LeafAnswer;
+
+    fn is_successful<T>(answer: &Result<LeafAnswer, T>) -> bool {
+        matches!(
+            answer,
+            Ok(LeafAnswer::True) | Ok(LeafAnswer::LeafAnswer { .. })
+        )
+    }
 
     #[test]
     #[cfg_attr(miri, ignore)]
@@ -1919,7 +1927,7 @@ mod test {
         let results = machine.run_query("current_input(S).").collect::<Vec<_>>();
 
         assert_eq!(results.len(), 1);
-        assert!(results[0].is_ok());
+        assert!(is_successful(&results[0]));
     }
 
     #[test]
@@ -1933,7 +1941,7 @@ mod test {
 
         assert_eq!(results.len(), 1);
         assert!(
-            results[0].is_ok(),
+            is_successful(&results[0]),
             "Expected read to succeed, got {:?}",
             results[0]
         );
@@ -1951,7 +1959,7 @@ mod test {
         let results = machine.run_query("current_output(S).").collect::<Vec<_>>();
 
         assert_eq!(results.len(), 1);
-        assert!(results[0].is_ok());
+        assert!(is_successful(&results[0]));
     }
 
     #[test]
@@ -1967,7 +1975,28 @@ mod test {
 
         assert_eq!(results.len(), 1);
         assert!(
-            results[0].is_ok(),
+            is_successful(&results[0]),
+            "Expected write to succeed, got {:?}",
+            results[0]
+        );
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)]
+    fn put_code_null_stream() {
+        // TODO: switch to a proper solution for configuring the machine with null streams
+        // once `StreamConfig` supports it.
+        let mut machine = MachineBuilder::new().build();
+        machine.user_output = Stream::Null(StreamOptions::default());
+        machine.configure_streams();
+
+        let results = machine
+            .run_query("put_code(user_output, 65).")
+            .collect::<Vec<_>>();
+
+        assert_eq!(results.len(), 1);
+        assert!(
+            is_successful(&results[0]),
             "Expected write to succeed, got {:?}",
             results[0]
         );
@@ -1987,9 +2016,45 @@ mod test {
 
         assert_eq!(results.len(), 1);
         assert!(
-            results[0].is_ok(),
+            is_successful(&results[0]),
             "Expected write to succeed, got {:?}",
             results[0]
         );
     }
+
+    #[test]
+    #[cfg_attr(miri, ignore)]
+    fn at_end_of_stream_0_null_stream() {
+        let mut machine = MachineBuilder::new()
+            .with_streams(StreamConfig::in_memory())
+            .build();
+
+        let results = machine.run_query("at_end_of_stream.").collect::<Vec<_>>();
+
+        assert_eq!(results.len(), 1);
+        assert!(
+            is_successful(&results[0]),
+            "Expected at_end_of_stream to succeed, got {:?}",
+            results[0]
+        );
+    }
+
+    #[test]
+    #[cfg_attr(miri, ignore)]
+    fn at_end_of_stream_1_null_stream() {
+        let mut machine = MachineBuilder::new()
+            .with_streams(StreamConfig::in_memory())
+            .build();
+
+        let results = machine
+            .run_query("current_input(Stream), at_end_of_stream(Stream).")
+            .collect::<Vec<_>>();
+
+        assert_eq!(results.len(), 1);
+        assert!(
+            is_successful(&results[0]),
+            "Expected at_end_of_stream to succeed, got {:?}",
+            results[0]
+        );
+    }
 }