From: Mark Thom Date: Sat, 14 Mar 2020 09:04:11 +0000 (-0600) Subject: Give new answer variables readable names (#279) X-Git-Tag: v0.8.119~43 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=31258247b310812fe5d354cdf1a845c8610f54b4;p=scryer-prolog.git Give new answer variables readable names (#279) --- diff --git a/src/prolog/machine/system_calls.rs b/src/prolog/machine/system_calls.rs index 137c5ce0..962d3cce 100644 --- a/src/prolog/machine/system_calls.rs +++ b/src/prolog/machine/system_calls.rs @@ -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; diff --git a/src/prolog/toplevel.pl b/src/prolog/toplevel.pl index 8efc0375..6d869e70 100644 --- a/src/prolog/toplevel.pl +++ b/src/prolog/toplevel.pl @@ -65,6 +65,49 @@ 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), @@ -122,19 +165,20 @@ '$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