/** * @predicate print_sso(+A) * Print the structure and contents of a term after converting it to a string. * This predicate ensures that a new line is printed if needed, and it prints * each element of the term's structure. * * @param A The input term to be printed. * * @example * ?- print_sso(some_term). * Output: * print_sso(l([])) */ print_sso(A):- % Ensure any needed newline is printed must_det_ll(( nl_if_needed, % Convert the term A into a string representation into_ss_string(A,SS),!, % Decompose SS into its list structure SS = ss(L,Lst), % Print the list length or structure of L writeln(print_sso(l(L))), % Print each member of Lst forall(member(S,Lst),writeln(S)), % Print a newline if needed nl_if_needed)),!. /** * @predicate var_or_number(+V) * Succeeds if the given term is either a variable or an integer. * * @param V The input term to check. * * @example * ?- var_or_number(X). * true. * * ?- var_or_number(5). * true. */ var_or_number(V):- % Succeeds if V is a variable var(V),!. var_or_number(V):- % Succeeds if V is an integer integer(V),!. /** * @predicate find_longest_len(+SL, -L) * Find the longest string in a list of strings. * This variant defaults to using a starting comparison length of 10. * * @param SL A list of strings to compare. * @param L The length of the longest string. * * @example * ?- find_longest_len(["apple", "banana", "cherry"], L). * L = 6. */ find_longest_len(SL,L):- % Call helper with default initial value 10 find_longest_len(SL,10,L),!. /** * @predicate find_longest_len(+SL, +N, -L) * Find the longest string in a list, comparing their lengths. * * @param SL A list of strings. * @param N The current maximum length. * @param L The final maximum length. */ find_longest_len([],L,L). % Base case: empty list, return current max length find_longest_len([S|SS],N,L):- % Find the length of string S print_length(S,N2), % Compare the current max length N with the new length N2, get max in NM max_min(N,N2,NM,_), % Recursively find the longest in the remaining strings find_longest_len(SS,NM,L). /* * Meta-predicate directive, specifying that print_with_pad takes a goal * as an argument (i.e., a predicate that can be called within it). */ :- meta_predicate(print_with_pad(0)). :- export(print_with_pad/1). % Export this predicate for external use /* * previously: The following commented-out version of print_with_pad * was likely used to calculate the line position manually, but was replaced * due to more efficient or specialized logic in the active version. * * print_with_pad(Goal):- * (line_position(current_output,O);O=0),!, * O1 is O+1, * call_w_pad(O1,Goal). */ /** * @predicate print_with_pad(:Goal) * Print a padded output by adjusting the position of the text. * * @param Goal The goal or content to print with padding. */ print_with_pad(Goal):- % Get the current output position or default to 0 (line_position(current_output,O);O=0),!, % Increment the position for padding O1 is O+1, % Convert Goal into a string for printing wots(S,Goal), % Call print_w_pad with the new position and string print_w_pad(O1,S). /** * @predicate into_s(+Text, -S) * Converts various types of input (text or objects) into a string. * * @param Text The input text or object to convert. * @param S The resulting string. */ into_s(Text,S):- % Try to convert Text to a string, fail silently on errors notrace(catch(text_to_string(Text,S),_,fail)),!. into_s(Obj,S):- % Convert object Obj to string using wots_hs wots_hs(S,pp(Obj)),!. /** * @predicate print_w_pad(+Pad, +Text) * Print text with padding. * * @param Pad The amount of padding before the text. * @param Text The text to print. */ print_w_pad(Pad,Text):- % Convert Text to a string and split it by newline into_s(Text,S), atomics_to_string(L,'\n',S) -> % Map over each line, printing with padding my_maplist(print_w_pad0(Pad),L). /** * @predicate print_w_pad0(+Pad, +S) * Helper predicate to print a single line of text with padding. * * @param Pad The amount of padding. * @param S The string to print. */ print_w_pad0(Pad,S):- % Print newline if necessary nl_if_needed, % Print Pad number of dashes (' ') for padding dash_chars(Pad,' '), % Write the string S write(S). :- meta_predicate(call_w_pad_prev(+,0)). call_w_pad_prev(Pad,Goal):- wots_hs(S,Goal), print_w_pad(Pad,S). %call_w_pad(N,Goal):- wants_html,!,format('',[N]),call_cleanup(call(Goal),write('')). :- meta_predicate(call_w_pad(+,0)). call_w_pad(_N,Goal):- wants_html,!,format('',[]),call_cleanup(call(Goal),write('')). call_w_pad(N,Goal):- nl_if_needed,wots_hs(S,dash_chars(N,' ')),!,pre_pend_each_line(S,Goal). maybe_print_pre_pended(Out,Pre,S):- atomics_to_string(L,'\n',S), maybe_print_pre_pended_L(Out,Pre,L). maybe_print_pre_pended_L(Out,_,[L]):- write(Out,L),!,flush_output(Out). maybe_print_pre_pended_L(Out,Pre,[H|L]):- write(Out,H),nl(Out),!,write(Out,Pre),maybe_print_pre_pended_L(Out,Pre,L). %pre_pend_each_line(_,Goal):- !,ignore(Goal). :- meta_predicate(pre_pend_each_line(+,0)). pre_pend_each_line(Pre,Goal):- write(Pre),pre_pend_each_line0(Pre,Goal). pre_pend_each_line0(Pre,Goal):- current_output(Out), current_predicate(predicate_streams:new_predicate_output_stream/2),!, call(call,predicate_streams:new_predicate_output_stream([Data]>>maybe_print_pre_pended(Out,Pre,Data),Stream)), arc_set_stream(Stream,tty(true)), %arc_set_stream(Stream,buffer(false)), %undo(ignore(catch(close(Stream),_,true))),!, setup_call_cleanup(true, (with_output_to_each(Stream,once(Goal)),flush_output(Stream)), ignore(catch(close(Stream),_,true))),!. pre_pend_each_line0(Pre,Goal):- with_output_to_each(string(Str),Goal)*->once((maybe_print_pre_pended(current_output,Pre,Str),nl_if_needed)). end_of_file. run_source_code(ShareVars, SourceCode, Vs, QQ):- QQ = source_buffer(SourceCode,Vs),!, %print(term=Sourcecode -> vs=Vs), maplist(share_vars(Vs),ShareVars), (\+ is_list(SourceCode) -> mort(SourceCode) ; maplist(mort,SourceCode)). run_source_code(ShareVars, Vs, QQ):- QQ = source_buffer(SourceCode,Vs),!, %print(term=Sourcecode -> vs=Vs),