]> Repositorios git - scryer-prolog.git/commitdiff
Give new answer variables readable names (#279)
authorMark Thom <[email protected]>
Sat, 14 Mar 2020 09:04:11 +0000 (03:04 -0600)
committerMark Thom <[email protected]>
Sat, 14 Mar 2020 09:04:11 +0000 (03:04 -0600)
src/prolog/machine/system_calls.rs
src/prolog/toplevel.pl

index 137c5ce08780cab12c892550f08db149ca909058..962d3ccee1d783238859bbf9c041e0b557e3b1d7 100644 (file)
@@ -728,7 +728,7 @@ impl MachineState {
                 let stream = current_input_stream.clone();
 
                 match addr {
-                    addr if addr.is_ref() => {                        
+                    addr if addr.is_ref() => {
                         self.unify(Addr::Stream(stream), addr);
                     }
                     Addr::Stream(other_stream) => {
@@ -747,14 +747,14 @@ impl MachineState {
 
                         return Err(self.error_form(err, stub));
                     }
-                }                
+                }
             }
             &SystemClauseType::CurrentOutput => {
                 let addr = self.store(self.deref(self[temp_v!(1)].clone()));
                 let stream = current_output_stream.clone();
 
                 match addr {
-                    addr if addr.is_ref() => {                        
+                    addr if addr.is_ref() => {
                         self.unify(Addr::Stream(stream), addr);
                     }
                     Addr::Stream(other_stream) => {
@@ -1128,25 +1128,35 @@ impl MachineState {
                     Addr::Con(Constant::Atom(name, _)) => {
                         let c = name.as_str().chars().next().unwrap();
                         let a2 = self[temp_v!(2)].clone();
+                        let c = Integer::from(c as u32);
 
-                        self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
+                        self.unify(Addr::Con(Constant::Integer(c)), a2);
                     }
                     Addr::Con(Constant::Char(c)) => {
                         let a2 = self[temp_v!(2)].clone();
-                        self.unify(Addr::Con(Constant::CharCode(c as u32)), a2);
+                        let c = Integer::from(c as u32);
+
+                        self.unify(Addr::Con(Constant::Integer(c)), a2);
                     }
-                    ref addr if addr.is_ref() => {
+                    addr if addr.is_ref() => {
                         let a2 = self[temp_v!(2)].clone();
 
                         match self.store(self.deref(a2)) {
-                            Addr::Con(Constant::Char(code)) => {
-                                self.unify(Addr::Con(Constant::Char(code)), addr.clone())
+                            Addr::Con(Constant::CharCode(code)) => {
+                                if let Some(c) = std::char::from_u32(code) {
+                                    self.unify(Addr::Con(Constant::Char(c)), addr);
+                                } else {
+                                    self.fail = true;
+                                }
                             }
                             Addr::Con(Constant::Integer(n)) => {
                                 let c = self.int_to_char_code(&n, "char_code", 2)?;
-                                let c = std::char::from_u32(c).unwrap();
 
-                                self.unify(Addr::Con(Constant::Char(c)), addr.clone());
+                                if let Some(c) = std::char::from_u32(c) {
+                                    self.unify(Addr::Con(Constant::Char(c)), addr);
+                                } else {
+                                    self.fail = true;
+                                }
                             }
                             _ => self.fail = true,
                         };
@@ -1233,7 +1243,7 @@ impl MachineState {
             &SystemClauseType::GetChar => {
                 let mut iter = parsing_stream(current_input_stream.clone());
                 let result = iter.next();
-                
+
                 let a1 = self[temp_v!(1)].clone();
 
                 match result {
@@ -2326,7 +2336,7 @@ impl MachineState {
                     enable_raw_mode().expect("failed to transition into raw mode");
                    let result = next_keypress();
                     disable_raw_mode().expect("failed to transition out of raw mode");
-                    
+
                     result
                };
 
@@ -2371,7 +2381,7 @@ impl MachineState {
                         // get the call site so that the number of active permanent variables can be read
                         // from it later.
                         let cp = (self.stack.index_and_frame(e).prelude.cp - 1).unwrap();
-                        
+
                         let p = cp.as_functor(&mut self.heap);
                         let e = self.stack.index_and_frame(e).prelude.e;
 
index 8efc037534c2e04e7711441e874b8b30a389ded0..6d869e70f586ae28af41d78747fa097d9da9a58d 100644 (file)
        memberchk(EqSpec, [fx,xfx,yfx])
     ).
 
+'$fabricate_var_name'(VarName, N) :-
+    char_code('A', AC),
+    LN is N mod 26 + AC,
+    char_code(LC, LN),
+    NN is N // 26,
+    (  NN =:= 0 ->
+       atom_chars(VarName, ['_', LC])
+    ;  number_chars(NN, NNChars),
+       atom_chars(VarName, ['_', LC | NNChars])
+    ).
+
+'$var_list_contains_name'([VarName = _ | VarList], VarName0) :-
+    (  VarName == VarName0 -> true
+    ;  '$var_list_contains_name'(VarList, VarName0)
+    ).
+
+'$var_list_contains_variable'([_ = Var | VarList], Var0) :-
+    (  Var == Var0 -> true
+    ;  '$var_list_contains_variable'(VarList, Var0)
+    ).
+
+'$make_new_var_name'(V, VarName, N, N1, VarList) :-
+    '$fabricate_var_name'(VarName0, N),
+    (  '$var_list_contains_name'(VarList, VarName0) ->
+       N0 is N + 1,
+       '$make_new_var_name'(V, VarName, N0, N1, VarList)
+    ;  VarName = VarName0,
+       N1 is N + 1
+    ).
+    
+'$extend_var_list'(Value, VarList, NewVarList) :-
+    term_variables(Value, Vars),
+    '$extend_var_list_'(Vars, 0, VarList, NewVarList).
+
+'$extend_var_list_'([], N, VarList, VarList).
+'$extend_var_list_'([V|Vs], N, VarList, NewVarList) :-
+    (  '$var_list_contains_variable'(VarList, V) ->
+       '$extend_var_list_'(Vs, N, VarList, NewVarList)
+    ;  '$make_new_var_name'(V, VarName, N, N1, VarList),
+       NewVarList = [VarName = V | NewVarList0],
+       '$extend_var_list_'(Vs, N1, VarList, NewVarList0)
+    ).
+
 '$write_goal'(G, VarList) :-
     (  G = (Var = Value) ->
        write(Var),
     '$graphic_token_char'(Char).
 
 '$write_eqs_and_read_input'(B, VarList) :-
-    sort(VarList, SortedVarList),
+    '$extend_var_list'(VarList, VarList, NewVarList),
+    sort(NewVarList, SortedVarList),
     '$get_b_value'(B0),
-    '$gather_goals'(SortedVarList, VarList, Goals),
+    '$gather_goals'(SortedVarList, SortedVarList, Goals),
     (  B0 == B ->
        (  Goals == [] ->
          write('true.'), nl
        ;  thread_goals(Goals, ThreadedGoals, (',')),
-         '$write_eq'(ThreadedGoals, VarList),
+         '$write_eq'(ThreadedGoals, NewVarList),
          write('.'),
          nl
        )
     ;  thread_goals(Goals, ThreadedGoals, (',')),
-       '$write_eq'(ThreadedGoals, VarList),
+       '$write_eq'(ThreadedGoals, NewVarList),
        '$raw_input_read_char'(C),
        (  C == (';'), !,
          write(' ;'), nl, false