diff --git a/hyperon-wam.vpj b/hyperon-wam.vpj
index ed6837cb7f3..bfe652142cf 100755
--- a/hyperon-wam.vpj
+++ b/hyperon-wam.vpj
@@ -67,6 +67,8 @@
Name="Other Files"
Filters="">
+
+
@@ -279,6 +281,4 @@
Recurse="1"
Excludes=".git/;*.metta.html;*.bak;build/;.*/;*~*/"/>
-
-
diff --git a/src/canary/metta_compiler.pl b/src/canary/metta_compiler.pl
index 1530975f58c..3bf992241ac 100755
--- a/src/canary/metta_compiler.pl
+++ b/src/canary/metta_compiler.pl
@@ -140,7 +140,7 @@
% ?- compile_for_exec(RetResult, is(pi+pi), Converted).
compile_for_exec(Res,I,O):-
- %ignore(Res='$VAR'('RetResult')),
+ %ignore(Res='$VAR'('RetResult')),`
compile_for_exec0(Res,I,O),!.
compile_for_exec0(Res,I,eval_args(I,Res)):- is_ftVar(I),!.
@@ -180,10 +180,25 @@
%(var(HResult) -> (Result = HResult, HHead = Head) ;
% funct_with_result_is_nth_of_pred(HeadIs,AsFunction, Result, _Nth, Head)),
ast_to_prolog_aux([FnName/LenArgsPlus1],[assign,HResult,[call(FnName)|Args]],HeadC),
- format("~w",[NextBody]),
- ast_to_prolog([FnName/LenArgsPlus1],NextBody,NextBodyC)
+
+ output_language( ast, ((
+ \+ \+ (( no_conflict_numbervars(HeadC + NextBody),
+ %write_src_wi([=,HeadC,NextBody]),
+ print_tree_nl([=,HeadC,NextBody]),
+ true))))),
+
+
+ ast_to_prolog([FnName/LenArgsPlus1],NextBody,NextBodyC),
+ output_language(prolog, (print_pl_source(Converted))),
+ true
)).
+
+no_conflict_numbervars(Term):-
+ findall(N,(sub_term(E,Term),compound(E), '$VAR'(N)=E, integer(N)),NL),!,
+ max_list([-1|NL],Max),Start is Max + 1,!,
+ numbervars(Term,Start,_,[attvar(skip),singletons(true)]).
+
%compile_for_assert(HeadIs, AsBodyFn, Converted) :-
% format("compile_for_assert: ~w ~w\n",[HeadIs, AsBodyFn]),
% HeadIs=[FnName|Args],
@@ -426,7 +441,7 @@
findall(Atom1, (between(1, Am1, I1), Atom1='$VAR'(I1)), AtomList1),
B=..[u_assign,[F|AtomList1],'$VAR'(A)],
(enable_interpreter_calls -> G=true;G=fail),
- create_and_consult_temp_file(Space,Fp/A,[H:-(format("######### warning: using stub for:~w\n",[F]),G,B)]))).
+ create_and_consult_temp_file(Space,Fp/A,[H:-(format("; % ######### warning: using stub for:~w\n",[F]),G,B)]))).
% Predicate to create a temporary file and write the tabled predicate
create_and_consult_temp_file(Space,F/A, PredClauses) :-
@@ -434,6 +449,10 @@
% Generate a unique temporary memory buffer
tmp_file_stream(text, TempFileName, TempFileStream),
% Write the tabled predicate to the temporary file
+ format(TempFileStream, ':- multifile((~q)/~w).~n', [metta_compiled_predicate, 3]),
+ format(TempFileStream, ':- dynamic((~q)/~w).~n', [metta_compiled_predicate, 3]),
+ format(TempFileStream, '~N~q.~n',[metta_compiled_predicate(Space,F,A)]),
+
format(TempFileStream, ':- multifile((~q)/~w).~n', [F, A]),
format(TempFileStream, ':- dynamic((~q)/~w).~n', [F, A]),
%if_t( \+ option_value('tabling',false),
@@ -444,16 +463,26 @@
% Consult the temporary file
% abolish(F/A),
/*'&self':*/
+ % sformat(CAT,'cat ~w',[TempFileName]), shell(CAT),
consult(TempFileName),
- listing(F/A),
+ % listing(F/A),
% Delete the temporary file after consulting
%delete_file(TempFileName),
- asserta(metta_compiled_predicate(Space,F,A)),
current_predicate(F/A),
- listing(metta_compiled_predicate/3),
+ %listing(metta_compiled_predicate/3),
true)).
+
+write_to_streams(StreamList, Format, Args) :-
+ % Write to each stream in the list
+ forall(member(Stream, StreamList),
+ format(Stream, Format, Args)),
+ % Write to stdout
+ format(user_output, Format, Args),
+ flush_output(user_output). % Ensure output is displayed immediately
+
+
%metta_compiled_predicate(_,F,A):- metta_compiled_predicate(F,A).
% Helper predicate to write a clause to the file
@@ -523,6 +552,15 @@
atom(Fn),
compile_flow_control(HeadIs,RetResult,Convert, Converted),!.
+f2p(HeadIs,RetResult, Convert, Converted) :- HeadIs\=@=Convert,
+ Convert=[Fn|_], \+ atom(Fn),
+ Args = Convert,
+ maplist(f2p(HeadIs),NewArgs, Args, NewCodes),
+ append(NewCodes,CombinedNewCode),
+ Code=[assign,RetResult,list(NewArgs)],
+ append(CombinedNewCode,[Code],Converted).
+
+
f2p(HeadIs,RetResult, Convert, Converted) :- HeadIs\=@=Convert,
Convert=[Fn|Args],
atom(Fn),!,
diff --git a/src/canary/metta_compiler_lib.pl b/src/canary/metta_compiler_lib.pl
index 3ea786ff7dd..59f6cf8c093 100644
--- a/src/canary/metta_compiler_lib.pl
+++ b/src/canary/metta_compiler_lib.pl
@@ -44,3 +44,6 @@
mc__assertEqualToResult(A, B, C) :- u_assign([assertEqualToResult, A, B], C).
+
+
+mc__empty(_):-!,fail.
diff --git a/src/canary/metta_debug.pl b/src/canary/metta_debug.pl
index 4999ccaf425..261001debec 100755
--- a/src/canary/metta_debug.pl
+++ b/src/canary/metta_debug.pl
@@ -762,6 +762,69 @@
is_showing(Flag) :- is_verbose(Flag), !.
is_showing(Flag) :- fast_option_value(Flag, 'show'), !.
+
+log_file_type(X):- nonvar(X),!,log_file_type(Is),!,Is=X.
+log_file_type(metta):- fast_option_value(compile, full),!.
+log_file_type(prolog):- fast_option_value(compile, save),!.
+log_file_type(markdown):- fast_option_value(format, markdown),!.
+log_file_type(metta):- fast_option_value(compile, false),!.
+log_file_type(prolog).
+
+
+into_blocktype(InfoType,Goal):- !,
+ enter_markdown(InfoType),!,
+ Goal.
+ %setup_call_cleanup(format('~N```~w~n',[InfoType]),Goal, format('~N```~n',[])).
+
+into_blocktype(InfoType,Goal):- log_file_type(markdown), !,
+ setup_call_cleanup(format('~N```~w~n',[InfoType]),Goal, format('~N```~n',[])).
+
+into_blocktype(InfoType,Goal):- log_file_type(prolog), !,
+ setup_call_cleanup(format('~N```~w~n',[InfoType]),Goal, format('~N```~n',[])).
+
+into_blocktype(InfoType,Goal):- log_file_type(prolog), !,
+ setup_call_cleanup(format('~N/*~n```~w~n*/~n',[InfoType]),Goal, format('~N/*~n```~n*/~n',[])).
+
+output_language( InfoType, Goal ) :- log_file_type(Lang), !, % (Lang==prolog; Lang==metta),!,
+ ((InfoType == Lang -> (must_det_ll((enter_markdown(Lang),leave_comment)),call(Goal)) ; (must_det_ll(enter_comment),into_blocktype(InfoType,Goal)))).
+
+output_language( InfoType, Goal ) :- log_file_type(markdown), !, into_blocktype(InfoType,Goal).
+output_language( comment, Goal ) :- log_file_type(markdown), !, call(Goal).
+output_language( comment, Goal ) :- log_file_type(prolog), !, format('~N:- q.~n', [output_language( comment, Goal)]).
+output_language( comment, Goal ) :- log_file_type(metta), !, in_cmt(Goal).
+
+
+:- dynamic(inside_comment/0).
+leave_comment:- inside_comment,!, format('~N*/~n~n'),retract(inside_comment).
+leave_comment.
+enter_comment:- inside_comment,!.
+enter_comment:- format('~N~n/*~n'),assert(inside_comment).
+:- enter_comment.
+
+:- at_halt(leave_markdown(_)).
+:- at_halt(leave_comment).
+
+
+:- dynamic(inside_markdown/1).
+leave_markdown(_):- \+ inside_markdown(_),!.
+leave_markdown(Lang):- inside_markdown(Lang),!, format('~N```~n'),retract(inside_markdown(Lang)).
+leave_markdown(_):- !. % inside_markdown(Other),!,leave_markdown(Other).
+leave_markdown(_Lang):- !. %format('~N```~n'),!.
+enter_markdown(Lang):- inside_markdown(Lang),!.
+enter_markdown(Lang):- inside_markdown(Other),!,leave_markdown(Other),!,enter_markdown(Lang).
+enter_markdown(Lang):- log_file_type(Us),Us=Lang,inside_comment,!,format('~N```~w~n',[Lang]),asserta(inside_markdown(Lang)),leave_comment.
+enter_markdown(Lang):- format('~N```~w~n',[Lang]),asserta(inside_markdown(Lang)).
+
+
+pick_quote(String, '"'):- \+ string_contains(String,'"'),!.
+pick_quote(String, '\''):- \+ string_contains(String,'\''),!.
+pick_quote(String, '`'):- \+ string_contains(String,'`'),!.
+
+banner_writeln(Msg):-
+ writeln('/*===='),
+ writeln(Msg),
+ writeln('====*/'),!.
+
%! if_show(+Flag, :Goal) is nondet.
%
% Conditionally execute a goal if showing is enabled for the given flag.
diff --git a/src/canary/metta_interp.pl b/src/canary/metta_interp.pl
index f25d993c210..c026977df81 100755
--- a/src/canary/metta_interp.pl
+++ b/src/canary/metta_interp.pl
@@ -652,7 +652,9 @@
redo_call_cleanup(set_prolog_IO(user_input, Out,user_error), G,
set_prolog_IO(user_input,COut,user_error)).
- not_compatio(G):- if_t(once(is_mettalog;is_testing),user_err(G)).
+not_compatio(G):- nb_current(in_not_compatio, true),!,call(G).
+not_compatio(G):- if_t(once(is_mettalog;is_testing; (\+ is_compatio )),
+ user_err( locally(nb_setval(in_not_compatio, true), G))).
extra_answer_padding(_).
@@ -1287,7 +1289,7 @@
assert_preds(Self,Load,Preds):-
expand_to_hb(Preds,H,_B),
functor(H,F,A), %trace,
- if_t((show_transpiler),
+ if_t((false,show_transpiler),
color_g_mesg_ok('#005288',(
ignore((
% \+ predicate_property(H,defined),
@@ -1527,10 +1529,11 @@
metta_anew(Load,_Src,OBO):- silent_loading,!,metta_anew1(Load,OBO).
metta_anew(Load,Src,OBO):-
not_compat_io((
- if_show(load,color_g_mesg('#ffa500', ((format('~N '), write_src(Src))))),
+ output_language( metta, (if_show(load, color_g_mesg('#ffa500', ((format('~N '), write_src(Src))))))),
% format('~N'),
- if_verbose(load,color_g_mesg('#0f0f0f',(write(' ; Action: '),writeq(Load=OBO),nl))))),
- metta_anew1(Load,OBO),not_compat_io((format('~N'))).
+ output_language( Load, (if_verbose(load,color_g_mesg('#4f4f0f', (( (write('; Action: '),writeq(Load=OBO),nl))))))),
+ true)),
+ metta_anew1(Load,OBO),not_compat_io((format('~N'))).
subst_vars_not_last(A,B):-
functor(A,_F,N),arg(N,A,E),
@@ -1574,7 +1577,7 @@
wots(S,write_src(exec(Exec))),
nb_setval(exec_src,Exec),
format('~N'),
- ignore((notrace((color_g_mesg('#0D6328',writeln(S)))))).
+ output_language(metta,ignore((notrace((color_g_mesg('#0D6328',writeln(S))))))).
%!(let* (( ($a $b) (collapse (get-atoms &self)))) ((bind! &stdlib $a) (bind! &corelib $b)))
@@ -1777,7 +1780,7 @@
do_metta_exec(From,Self,TermV,FOut):-
Output = X,
%format("########################X0 ~w ~w ~w\n",[Self,TermV,FOut]),
- (catch(((not_compatio(write_exec(TermV)),
+ (catch(((output_language(metta,write_exec(TermV)),
notrace(into_metta_callable(Self,TermV,Term,X,NamedVarsList,Was)),!,
%format("########################X1 ~w ~w ~w ~w\n",[Term,X,NamedVarsList,Output]),
user:interactively_do_metta_exec(From,Self,TermV,Term,X,NamedVarsList,Was,Output,FOut))),
@@ -1811,7 +1814,10 @@
subst_vars(Res+ExecGoal,Res+Term,NamedVarsList),
copy_term_g(NamedVarsList,Was),
term_variables(Term,Vars),
- notrace((color_g_mesg('#114411',print_pl_source(answer(Res):-ExecGoal)))),
+
+
+ Call = do_metta_runtime(Res, ExecGoal),
+ output_language(prolog, notrace((color_g_mesg('#114411', print_pl_source(:- Call ))))),
%nl,writeq(Term),nl,
((\+ \+
((
@@ -1846,6 +1852,8 @@
current_self(SelfS),SelfS==Self,!,
do_metta(true,exec,Self,Form,_Out).
eval_H(Term,X):- catch_metta_return(eval_args(Term,X),X).
+
+eval_H(StackMax,Self,Term,X):- fast_option_value(compile, save),!.
eval_H(StackMax,Self,Term,X):- catch_metta_return(eval_args('=',_,StackMax,Self,Term,X),X).
/*
eval_H(StackMax,Self,Term,X).
@@ -2231,6 +2239,9 @@
:- ensure_loaded(metta_python).
:- ensure_loaded(metta_corelib).
%:- ensure_loaded(metta_help).
+
+:- enter_comment.
+
:- initialization(use_corelib_file).
:- initialization(use_metta_ontology).
@@ -2255,7 +2266,86 @@
%:- initialization(loon(program),program).
%:- initialization(loon(default)).
+% Flush any pending output to ensure smooth runtime interactions
+flush_metta_output :-
+ with_output_to(user_error, (write_answer_output, ttyflush)).
+
+% Write out answers in hyperon-experimental format to user_error
+metta_runtime_write_answers(List) :-
+ with_output_to(user_error, (write('['), write_answers_aux(List), write(']'))).
+
+% Helper predicate to manage answer formatting to user_error
+write_answers_aux([]) :- !.
+write_answers_aux([H|T]) :-
+ with_output_to(user_error, (write_src_woi(H), (T == [] -> true ; write(', '), write_answers_aux(T)))).
+
+% Dynamically describe the current file or an actively reading file, providing context for runtime sessions
+file_desc(Message) :-
+ prolog_load_context(file, CurrentFile),
+ ( stream_property(Stream, mode(read)),
+ stream_property(Stream, file_name(File)),
+ \+ at_end_of_stream(Stream),
+ File \= CurrentFile,
+ !,
+ sformat(Message, 'File(~w)', [File])
+ ; sformat(Message, 'File(~w)', [CurrentFile])
+ ).
+
+:- dynamic(runtime_session/4).
+
+% Begin a runtime session with detailed time recording, output to user_error
+begin_metta_runtime :-
+ file_desc(Description),
+ current_times(WallStart, CPUStart),
+ asserta(runtime_session(start, WallStart, CPUStart, Description)),
+ with_output_to(user_error, format('~w started.~n', [Description])).
+
+% End a runtime session, calculate and print elapsed times, output to user_error
+end_metta_runtime :-
+ file_desc(Description),
+ ( retract(runtime_session(start, WallStart, CPUStart, Description))
+ -> calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime),
+ print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description)
+ ; with_output_to(user_error, format('Error: No runtime session start information found for "~w".~n', [Description]))
+ ).
+
+% Wall and CPU time
+current_times(WallStart, CPUStart) :-
+ get_time(WallStart),
+ statistics(cputime, CPUStart).
+
+% Calculate elapsed times
+calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime) :-
+ current_times(WallEnd, CPUEnd),
+ WallElapsedTime is WallEnd - WallStart,
+ CPUElapsedTime is CPUEnd - CPUStart.
+
+% Print the elapsed wall and CPU time with a description, output to user_error
+print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description) :-
+ with_output_to(user_error,
+ format(' % Walltime: ~9f seconds, CPUtime: ~9f seconds for ~w~n',
+ [WallElapsedTime, CPUElapsedTime, Description])).
+
+% Execute a Prolog query and handle output, performance logging, and time measurements to user_error
+do_metta_runtime(_Var,_Call) :- fast_option_value(compile, save),!.
+do_metta_runtime( Var, Call) :-
+ functor(Call, Func, _),
+ atom_concat('Testing ', Func, Description),
+ current_times(WallStart, CPUStart),
+ % Execute the query and collect results
+ with_output_to(user_error, findall(Var, Call, List)),
+ % Record stop time
+ calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime),
+ % Show results
+ with_output_to(user_error, metta_runtime_write_answers(List)),
+ % Print elapsed time
+ print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description),
+ flush_metta_output.
+
+
+
:- set_prolog_flag(metta_interp,ready).
+%:- ensure_loaded(metta_runtime).
%:- set_prolog_flag(gc,false).
:- use_module(library(clpr)). % Import the CLP(R) library
diff --git a/src/canary/metta_parser.pl b/src/canary/metta_parser.pl
index d2f35f4666f..002c7b656b6 100644
--- a/src/canary/metta_parser.pl
+++ b/src/canary/metta_parser.pl
@@ -195,12 +195,17 @@
svar_fixvarname(SVAR, UP) :-
% If the name is already bound, throw an error.
nonvar(UP), !, trace_or_throw(nonvar_svar_fixvarname(SVAR, UP)).
+%
svar_fixvarname(SVAR, UP) :-
% Fix the name if it follows certain conventions.
svar_fixname(SVAR, UP), !.
svar_fixvarname(SVAR, UP) :-
% If fixing fails, throw an error.
fail, trace_or_throw(svar_fixname(SVAR, UP)).
+svar_fixvarname(SVAR, UP):- integer(SVAR),!,sformat(SUP,'~w',['$VAR'(SVAR)]), svar_fixvarname(SUP, UP).
+svar_fixvarname(SVAR, UP):- integer(SVAR),UP=SVAR,!.
+svar_fixvarname(SVAR, UP):- svar(SVAR,UP),!.
+svar_fixvarname(SVAR, UP):- n_to_vn(UP,SVAR),!.
%! svar_fixname(?Var, ?NameO) is det.
%
@@ -274,6 +279,9 @@
fix_varcase(Word, Word) :-
% If the word starts with '_', leave it unchanged.
atom_concat_or_rtrace('_', _, Word), !.
+
+fix_varcase(Word, WordC) :- string(Word),atom_string(Atom,Word),!,fix_varcase(Atom, WordC).
+fix_varcase(Word, WordC) :- atom(Word),downcase_atom(Word, UC),Word=UC,atom_concat('_',UC,WordC),!.
fix_varcase(Word, WordC) :-
% Convert the first letter to uppercase.
!, atom_codes(Word, [F | R]), to_upper(F, U), atom_codes(WordC, [U | R]).
@@ -818,15 +826,19 @@
maybe_name_vars(List):- \+ is_list(List), !.
maybe_name_vars([]):-!.
maybe_name_vars([N=Var|List]):-
- ignore((n_to_vn(N,NN),Var = '$VAR'(NN))),
+ must_det_ll((n_to_vn(N,NN), ignore((Var = '$VAR'(NN))))),
maybe_name_vars(List).
-n_to_vn(N,NN):- var(N),!,sformat(NN,'~p',[N]).
-n_to_vn(N,NN):- number(N),sformat(NN,'~p',['$VAR'(N)]).
-n_to_vn(N,NN):- \+ atom(N),!,sformat(NN,'~p',[N]).
-n_to_vn('_','_'):-!.
-n_to_vn(N,NN):-atom_concat('$',N1,N),!,sformat(NN,'~w',[N1]).
-n_to_vn(N,NN):-atom_concat('_',N1,N),!,sformat(NN,'~w',[N1]).
-n_to_vn(N,NN):-!,sformat(NN,'~w',[N]).
+
+n_to_vn(N,NN):- n_to_vn0(N,NNS),name(NN,NNS).
+n_to_vn0(N,NN):- var(N),!,sformat(NN,'~p',[N]).
+n_to_vn0(N,NN):- integer(N),sformat(NN,'~p',['$VAR'(N)]).
+n_to_vn0(N,NN):- number(N),sformat(NN,'~p',['$VAR'(N)]).
+n_to_vn0(N,NN):- string(N),!,atom_string(A,N),!,n_to_vn0(A,NN).
+n_to_vn0(N,NN):- \+ atom(N),!,sformat(NN,'_~p',[N]).
+n_to_vn0('_','_'):-!.
+n_to_vn0(N,NN):-atom_concat('$',N1,N),!,sformat(NN,'~w',[N1]).
+n_to_vn0(N,NN):-atom_concat('_',N1,N),!,sformat(NN,'_~w',[N1]).
+n_to_vn0(N,NN):-!,sformat(NN,'_~w',[N]).
better_typename(TypeName1,TypeName2,array):- var(TypeName1),var(TypeName2),!.
better_typename(TypeName1,TypeName2,TypeName1):- var(TypeName2),!.
@@ -1198,6 +1210,10 @@
; Symbolic = Symbol). % Otherwise, keep the symbol as is.
+
+% ast_to_prolog_aux(_,A,O) :- compound(A), A='$VAR'(String),svar_fixvarname(String,UP),O='$VAR'(UP),!.
+% ast_to_prolog_aux(DontStub,[assign,A,E],OO):- compound(A), A='$VAR'(String),svar_fixvarname(String,UP),String\=UP,O='$VAR'(UP),!,ast_to_prolog_aux(DontStub,[assign,O,E],OO).
+
%! classify_and_convert_charseq_(+Chars:list, -Symbolic:term) is det.
%
% Helper predicate that attempts to classify the character sequence.
@@ -1207,9 +1223,11 @@
% @param Symbolic The resultant Prolog term or symbol.
% Case 1: If the character sequence starts with '$', treat it as a variable.
-classify_and_convert_charseq_(['$'| RestChars], '$VAR'(Symbolic)) :-
+classify_and_convert_charseq_(['$'| RestChars], '$VAR'(SymbolicVar)) :-
!,
- atom_chars(Symbolic, ['_'|RestChars]). % Convert the rest of the characters into a variable name.
+ atom_chars(Symbolic, RestChars), % Convert the rest of the characters into a variable name.
+ svar_fixvarname(Symbolic,SymbolicVar).
+
% Case 2: Attempt to interpret the characters as a Prolog term using `read_from_chars/2`.
% This handles more complex syntaxes like numbers, dates, etc.
classify_and_convert_charseq_(Chars, Symbolic) :-
diff --git a/src/canary/metta_pfc_base.pl b/src/canary/metta_pfc_base.pl
index 33c6a3e4389..556bb69e0ac 100755
--- a/src/canary/metta_pfc_base.pl
+++ b/src/canary/metta_pfc_base.pl
@@ -2194,12 +2194,12 @@
%! pfcAddTrigger(+Trigger, +Support) is det.
%
-% Adds a trigger (positive, negative, or bidirectional) to the system,
+% Adds a trigger (positive, negative, or backward) to the system,
% asserting it with the provided support and evaluating it if applicable.
% Unrecognized triggers result in a warning message.
%
% @arg Trigger The trigger to be added, which can be a positive (`$pt$`),
-% negative (`$nt$`), or bidirectional (`$bt$`) trigger.
+% negative (`$nt$`), or backward (`$bt$`) trigger.
% @arg Support The support context for asserting the trigger.
%
% @example
@@ -2225,7 +2225,7 @@
\+ pfc_call(Test),
with_current_why(\+ pfc_call(Test), fcEvalLHS(Body, ((\+Trigger), '$nt$'(TriggerCopy, Test, Body)))).
pfcAddTrigger('$bt$'(Trigger, Body), Support) :-
- % Add a bidirectional trigger.
+ % Add a backward trigger.
!,
pfcAssert('$bt$'(Trigger, Body), Support),
pfcBtPtCombine(Trigger, Body, Support).
@@ -2235,16 +2235,16 @@
%! pfcBtPtCombine(+Head, +Body, +Support) is det.
%
-% Combines a bidirectional trigger (`$bt$`) with any positive triggers
+% Combines a backward trigger (`$bt$`) with any positive triggers
% (`$pt$`) that have unifying heads. For each unifying positive trigger,
-% the instantiated body of the bidirectional trigger is evaluated.
+% the instantiated body of the backward trigger is evaluated.
%
-% @arg Head The head of the bidirectional trigger.
-% @arg Body The body of the bidirectional trigger.
+% @arg Head The head of the backward trigger.
+% @arg Body The body of the backward trigger.
% @arg Support The support context for the combination.
%
% @example
-% % Combine a bidirectional trigger with matching positive triggers.
+% % Combine a backward trigger with matching positive triggers.
% ?- pfcBtPtCombine(my_head, my_body, support_context).
%
pfcBtPtCombine(Head, Body, Support) :-
@@ -3135,7 +3135,7 @@
%! fc_rule_check(+P) is nondet.
%
% Performs special built-in forward chaining if the input `P` is a rule.
-% It processes both unidirectional (`==>`) and bidirectional (`<==>`) rules.
+% It processes unidirectional (`==>`), bidirectional (`<==>`) and backward (`<-`) rules.
%
% @arg P The rule to process.
%
diff --git a/src/canary/metta_repl.pl b/src/canary/metta_repl.pl
index fed77b48e4d..dc4b5fd04b2 100755
--- a/src/canary/metta_repl.pl
+++ b/src/canary/metta_repl.pl
@@ -921,7 +921,7 @@
% Execute the form and generate the output using do_metta/5.
do_metta(true, exec, Self, Form, Out),
% Write the result to the source.
- write_src(Out).
+ output_language(metta_answers, write_src(Out)).
%! eval(+Form, -Out) is det.
% Evaluates a form and returns the output.
@@ -1205,21 +1205,23 @@
nb_setarg(1,Prev,Output))),
- if_t(ResNum=(not_compatio(format('~N~nDeterministic: ', [])), !); %or Nondet
+ output_language(answers,(if_t(ResNum=(old_not_compatio(format('~N~nDeterministic: ', [])), !); %or Nondet
/* previously: handle deterministic result output */
- (Complete==true -> (not_compatio(format('~N~nLast Result(~w): ',[ResNum])),! );
- not_compatio(format('~N~nNDet Result(~w): ',[ResNum]))))),
- ignore(((
- not_compatio(if_t( \+ symbolic(Output), nop(nl))),
+ (Complete==true -> (old_not_compatio(format('~N~nLast Result(~w): ',[ResNum])),! );
+ old_not_compatio(format('~N~nNDet Result(~w): ',[ResNum]))))),
+ ignore(((
+ if_t( \+ symbolic(Output), not_compatio(nop(nl))),
%if_t(ResNum==1,in_answer_io(format('~N['))),
- user_io(with_indents(is_mettalog,
- color_g_mesg_ok(yellow,
- \+ \+
+ % user_io
+ (with_indents(is_mettalog,
+ color_g_mesg_ok(yellow,
+ \+ \+
(maybe_name_vars(NamedVarsList),
- not_compatio(write_bsrc(Output)),
- true)))) )) ))),
- in_answer_io(write_asrc(Output)),
+ old_not_compatio(write_bsrc(Output)),
+ true)))) )) ))))),
+ in_answer_io(write_asrc((Output))),
not_compatio(extra_answer_padding(format('~N'))), % Just in case, add some virt space between answers
@@ -1237,8 +1239,8 @@
maplist(print_var,NamedVarsListR), nop(nl)))) ; true))))),
(
(Stepping==true) ->
- (write("~npress ';' for more solutions "),get_single_char_key(C),
- not_compatio((writeq(key=C),nl)),
+ (old_not_compatio(write("~npress ';' for more solutions ")),get_single_char_key(C),
+ old_not_compatio((writeq(key=C),nl)),
(C=='b' -> (once(repl),fail) ;
(C=='m' -> make ;
(C=='t' -> (nop(set_debug(eval,true)),rtrace) ;
@@ -1254,10 +1256,11 @@
(((Complete==true ->! ; true))))), not_compatio(extra_answer_padding(format('~N~n')))))
*-> (ignore(Result = res(FOut)),ignore(Output = (FOut)))
; (flag(result_num,ResNum,ResNum),(ResNum==0->
- (in_answer_io(nop(write('['))),not_compatio(format('~N~n~n')),!,true);true))),
+ (in_answer_io(nop(write('['))),old_not_compatio(format('~N~n~n')),!,true);true))),
in_answer_io(write(']\n')),
ignore(Result = res(FOut)).
+old_not_compatio(G):- call(G),ttyflush.
%! maybe_assign(+N_V) is det.
%
@@ -1787,7 +1790,10 @@
% Compile the goal for execution and store the result in Res.
compile_for_exec(Res, Exec, Goal),
% Print the compiled goal with formatting.
- notrace((color_g_mesg('#114411', print_pl_source(answer2(Res) :- Goal)))).
+ Call = do_metta_runtime(Res, Goal),
+ output_language(prolog, notrace((color_g_mesg('#114411', print_pl_source(:- Call))))),
+ call(Call).
+
%! verbose_unify(+Term) is det.
%
diff --git a/src/canary/metta_runtime.pl b/src/canary/metta_runtime.pl
index 3b96ec6d38a..37911819261 100644
--- a/src/canary/metta_runtime.pl
+++ b/src/canary/metta_runtime.pl
@@ -26,82 +26,8 @@
% Uncomment the next line if 'metta_compiler_lib' needs to be loaded as well
% :- user:ensure_loaded(metta_compiler_lib),!,
-:- user:ensure_loaded(metta_interp),!,
- % Start interpreter code
- user:loon.
+:- user:ensure_loaded(metta_interp),!.
-% Flush any pending output to ensure smooth runtime interactions
-flush_metta_output :-
- with_output_to(user_error, (write_answer_output, ttyflush)).
-
-% Write out answers in hyperon-experimental format to user_error
-metta_runtime_write_answers(List) :-
- with_output_to(user_error, (write('['), write_answers_aux(List), write(']'))).
-
-% Helper predicate to manage answer formatting to user_error
-write_answers_aux([]) :- !.
-write_answers_aux([H|T]) :-
- with_output_to(user_error, (write_src_woi(H), (T == [] -> true ; write(', '), write_answers_aux(T)))).
-
-% Dynamically describe the current file or an actively reading file, providing context for runtime sessions
-file_desc(Message) :-
- prolog_load_context(file, CurrentFile),
- ( stream_property(Stream, mode(read)),
- stream_property(Stream, file_name(File)),
- \+ at_end_of_stream(Stream),
- File \= CurrentFile,
- !,
- sformat(Message, 'File(~w)', [File])
- ; sformat(Message, 'File(~w)', [CurrentFile])
- ).
-
-:- dynamic(runtime_session/4).
-
-% Begin a runtime session with detailed time recording, output to user_error
-begin_metta_runtime :-
- file_desc(Description),
- current_times(WallStart, CPUStart),
- asserta(runtime_session(start, WallStart, CPUStart, Description)),
- with_output_to(user_error, format('~w started.~n', [Description])).
-
-% End a runtime session, calculate and print elapsed times, output to user_error
-end_metta_runtime :-
- file_desc(Description),
- ( retract(runtime_session(start, WallStart, CPUStart, Description))
- -> calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime),
- print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description)
- ; with_output_to(user_error, format('Error: No runtime session start information found for "~w".~n', [Description]))
- ).
-
-% Wall and CPU time
-current_times(WallStart, CPUStart) :-
- get_time(WallStart),
- statistics(cputime, CPUStart).
-
-% Calculate elapsed times
-calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime) :-
- current_times(WallEnd, CPUEnd),
- WallElapsedTime is WallEnd - WallStart,
- CPUElapsedTime is CPUEnd - CPUStart.
-
-% Print the elapsed wall and CPU time with a description, output to user_error
-print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description) :-
- with_output_to(user_error,
- format(' % Walltime: ~9f seconds, CPUtime: ~9f seconds for ~w~n',
- [WallElapsedTime, CPUElapsedTime, Description])).
-
-% Execute a Prolog query and handle output, performance logging, and time measurements to user_error
-do_metta_runtime(Var, Call) :-
- functor(Call, Func, _),
- atom_concat('Testing ', Func, Description),
- current_times(WallStart, CPUStart),
- % Execute the query and collect results
- with_output_to(user_error, findall(Var, Call, List)),
- % Record stop time
- calculate_elapsed_time(WallStart, CPUStart, WallElapsedTime, CPUElapsedTime),
- % Show results
- with_output_to(user_error, metta_runtime_write_answers(List)),
- % Print elapsed time
- print_elapsed_time(WallElapsedTime, CPUElapsedTime, Description),
- flush_metta_output.
+% Start interpreter code
+:- user:loon.