Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/builin_types.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_builtin_types)
!(import! &self lib/lib_builtin_types)

;; Test type definitions of arithmetic operators
!(test (get-type +) (-> Number Number Number))
Expand Down
13 changes: 0 additions & 13 deletions examples/curry.metta
Original file line number Diff line number Diff line change
@@ -1,16 +1,3 @@
(= (f $a $b) (+ $a $b))

(= (g $a $b $c) (+ $c (+ $a $b)))

(= (show) (repr (f 1)))

!(test (repr (f 1)) "(partial f (1))")
!(test ((f 1) 2) 3)
!(test (repr (g 1 2)) "(partial g (1 2))")

(= (h $A $B)
(append ($A) $B))

!(test ((h 42) (1 2 3)) (42 1 2 3))
!(test (repr (h 42)) "(partial h (42))")
!(test (map-atom (1 2 3) (+ 1)) (2 3 4))
2 changes: 1 addition & 1 deletion examples/fibsmartimport.metta
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
!(import! &self fibsmart)
!(import! &self examples/fibsmart)

!(test (fib 100) 354224848179261915075)
2 changes: 1 addition & 1 deletion examples/he_assert.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

!(test (assertEqual (+ 1 2) (- 6 3)) True)
!(test (assertAlphaEqual (h $x $y) (h $a $b)) True)
Expand Down
2 changes: 1 addition & 1 deletion examples/he_atomspace.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

!(add-atom &self (= (addnormal) (+ 1 3)))
!(add-reduct &self (= (addreduct) (+ 1 3)))
Expand Down
2 changes: 1 addition & 1 deletion examples/he_equalreduct.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

(= (add 1 2) 3)

Expand Down
2 changes: 1 addition & 1 deletion examples/he_error.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

!(test (let $result (catch (+ 40 2))
(if-error $result
Expand Down
2 changes: 1 addition & 1 deletion examples/he_evaluation.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

(= (double $x) (+ $x $x))

Expand Down
2 changes: 1 addition & 1 deletion examples/he_minimalmetta.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

(= (div $x $y $accum)
(chain (eval (- $x $y)) $r1
Expand Down
2 changes: 1 addition & 1 deletion examples/he_quoting.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

!(test (quote (+ 1 2)) (quote (+ 1 2)))

Expand Down
2 changes: 1 addition & 1 deletion examples/he_types.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_he)
!(import! &self lib/lib_he)

!(test (is-function (-> Atom Atom)) True)
!(test (is-function Atom) False)
Expand Down
2 changes: 1 addition & 1 deletion examples/llm_cities.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_llm)
!(import! &self lib/lib_llm)

;GPT LLM use case, extract country cities are located in:
!(let* (($city (superpose (stockholm vienna)))
Expand Down
2 changes: 1 addition & 1 deletion examples/nars_tuffy.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_nars)
!(import! &self lib/lib_nars)

(= (kb)
((Sentence ((==> (--> (× $1 $2) friend)
Expand Down
2 changes: 1 addition & 1 deletion examples/pln_roman.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_pln)
!(import! &self lib/lib_pln)

(= (STV A) (stv 0.5 0.9))
(= (STV B) (stv 0.25 0.9))
Expand Down
2 changes: 1 addition & 1 deletion examples/pln_tuffy.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_pln)
!(import! &self lib/lib_pln)

(= (STV (Concept Anna)) (stv 0.1667 0.9))
(= (STV (Concept Bob)) (stv 0.1667 0.9))
Expand Down
4 changes: 2 additions & 2 deletions examples/prologimport.metta
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
;%%% HIJACK PROLOG CONSULT TO LOAD PREDICATES AS FUNCTIONS %%%

;Let's allow us to use Prolog's consult and import_prolog_function in combination to import functions from a pl file:
!(import! &self ../lib/lib_import)
!(import! &self lib/lib_import)

;Let's use it to import myfunc, a predicate in function form convention defined as Prolog code in prologimport_example.pl:
!(import_prolog_functions_from_file "./examples/prologimport_example.pl" (myfunc))
Expand Down Expand Up @@ -89,4 +89,4 @@
!(test (myAddMeTTa 241) 242)

;and invocation as predicate:
!(test (let $temp (callPredicate (Predicate (myAddMeTTa 241 $x))) $x) 242)
;!(test (let $temp (callPredicate (Predicate (myAddMeTTa 241 $x))) $x) 242)
2 changes: 1 addition & 1 deletion examples/python_import.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self "python_import_file.py")
!(import! &self examples/python_import_file.py)

!(test (repr (py-call (python_import_file.greet "PeTTa User"))) "Hello, PeTTa User from Python!")
!(test (py-call (python_import_file.add 10 20)) 30)
2 changes: 1 addition & 1 deletion examples/roman_test.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_roman)
!(import! &self lib/lib_roman)
;Test hihger order functions
!(test (map-flat (+ 1) (1 2 3)) (2 3 4))
!(test (map-nested (+ 1) (1 (2 3))) (2 (3 4)))
Expand Down
2 changes: 1 addition & 1 deletion examples/spaces_find.metta
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
!(import! &self ../lib/lib_spaces)
!(import! &self lib/lib_spaces)

(friend a b)
(friend b c)
Expand Down
2 changes: 1 addition & 1 deletion examples/tilepuzzle.metta
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@
$_4 $_5 $_6
$_7 ___ $_8))

!(import! &self ../lib/lib_datastructures)
!(import! &self lib/lib_datastructures)

(= (bfs_loop (empty-queue) $N0) $N0)
(= (bfs_loop $Q $N0)
Expand Down
15 changes: 13 additions & 2 deletions run.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
SCRIPT_DIR=$(cd -- "$(dirname -- "$0")" && pwd)
if [ -f $SCRIPT_DIR/mork_ffi/target/release/libmork_ffi.so ]; then
LD_PRELOAD=$SCRIPT_DIR/mork_ffi/target/release/libmork_ffi.so \
swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- "$@" mork
swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- "$0" mork
elif [ $1 = "--compiler" ] ; then
echo "COMPILER called"
BASENAME=$(basename "${2}")
COMPILED_FILE=$(mktemp --suffix ".pl" "${TMPDIR}/${BASENAME}XXXXX")
echo "swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- --silent=true --mode=COMPILER -o ${COMPILED_FILE} ${2}"
swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- --silent=true --mode=COMPILER -o ${COMPILED_FILE} "${2}"
echo "COMPILED FILE: ${COMPILED_FILE}"
OUTPUT=$(swipl -s ${COMPILED_FILE} -g true -t halt)
echo "OUTPUT: ${COMPILED_FILE}"
rm ${COMPILED_FILE}
echo ${OUTPUT}
else
swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- "$@"
swipl --stack_limit=8g -q -s $SCRIPT_DIR/src/main.pl -- --silent=false --mode=INTERPRETER "$1"
fi
199 changes: 168 additions & 31 deletions src/filereader.pl
Original file line number Diff line number Diff line change
@@ -1,48 +1,185 @@
:- use_module(library(readutil)). % read_file_to_string/3
:- use_module(library(pcre)). % re_replace/4
:- current_prolog_flag(argv, Args), ( (memberchk(silent, Args) ; memberchk('--silent', Args) ; memberchk('-s', Args))
-> assertz(silent(true)) ; assertz(silent(false)) ).

%Read Filename into string S and process it (S holds MeTTa code):
% Read Filename into string S and compile it to Prolog (S holds MeTTa code)
compile_metta_file(Filename, Output) :- compile_metta_file(Filename, Output, '&self').
compile_metta_file(Filename, Output, Space) :-
read_file_to_string(Filename, S, []),
compile_metta_string(S, Output, Space).

% Read Filename into string S and process it:
load_metta_file(Filename, Results) :- load_metta_file(Filename, Results, '&self').
load_metta_file(Filename, Results, Space) :- read_file_to_string(Filename, S, []),
process_metta_string(S, Results, Space).
load_metta_file(Filename, Results, Space) :-
read_file_to_string(Filename, S, []),
process_metta_string(S, Results, Space).

% Compile function definitions, invocations and S-expression part of &self space
compile_metta_string(S, Output) :- compile_metta_string(S, Output, '&self').
compile_metta_string(S, Output, Space) :-
extract_forms(S, Forms),
maplist(parse_form, Forms, ParsedForms),
% Clean slate for specializations and translated_from facts
retractall(ho_specialization(_, _)),
retractall(translated_from(_, _)),
% Process forms and collect all goals (both functions and runnables) in order
maplist(process_form_for_compile(Space), ParsedForms, AllGoals), !,
% Now collect any specialized functions that were generated during compilation
findall(SpecGoals, collect_specialization_goals(SpecGoals), SpecializationGoalsList),
% Flatten and combine specialization goals with main goals
append(SpecializationGoalsList, SpecGoals),
append([SpecGoals, AllGoals], CombinedGoals),
% Build the main/0 predicate with all goals
build_main_predicate(CombinedGoals, MainClause),
Prologue = [
':- working_directory(CWD, CWD), string_concat(CWD_NOSLASH, "/", CWD), assertz(working_dir(CWD_NOSLASH)).\n',
':- getenv("PETTA_HOME", PETTA_HOME) -> assertz(petta_home(PETTA_HOME)) ; assertz(petta_home("")).\n',
':- assertz(silent(true)).\n',
':- petta_home(PETTA_HOME), string_concat(PETTA_HOME, "/src/metta", METTA_LIB), ensure_loaded(METTA_LIB).\n',
':- dynamic translated_from/2.\n\n'
],
Initialization = [
'\n:- initialization(main).\n'
],
append([Prologue, [MainClause], Initialization], OutputsList),
atomic_list_concat(OutputsList, Output).

%Extract function definitions, call invocations, and S-expressions part of &self space:
process_metta_string(S, Results) :- process_metta_string(S, Results, '&self').
process_metta_string(S, Results, Space) :- string_codes(S, Cs),
strip(Cs, 0, Codes),
phrase(top_forms(Forms, 1), Codes),
maplist(parse_form, Forms, ParsedForms),
maplist(process_form(Space), ParsedForms, ResultsList), !,
append(ResultsList, Results).
process_metta_string(S, Results, Space) :-
extract_forms(S, Forms),
maplist(parse_form, Forms, ParsedForms),
maplist(process_form(Space), ParsedForms, ResultsList, _), !,
append(ResultsList, Results).

% Extract top forms from MeTTa string
extract_forms(S, Forms) :-
string_codes(S, Cs),
strip(Cs, 0, Codes),
phrase(top_forms(Forms, 1), Codes).

%First pass to convert MeTTa to Prolog Terms and register functions:
parse_form(form(S), parsed(T, S, Term)) :- sread(S, Term),
( Term = [=, [F|W], _], atom(F) -> register_fun(F), length(W, N), Arity is N + 1, assertz(arity(F,Arity)), T=function
; T=expression ).
parse_form(runnable(S), parsed(runnable, S, Term)) :- sread(S, Term).

%Second pass to compile / run / add the Terms:
process_form(Space, parsed(expression, _, Term), []) :- 'add-atom'(Space, Term, true),
( silent(true) -> true ; swrite(Term,STerm),
format("\e[33m--> metta sexpr -->~n\e[36m~w~n", [STerm]),
format("\e[33m^^^^^^^^^^^^^^^^^^^~n\e[0m") ).
process_form(_, parsed(runnable, FormStr, Term), Result) :- translate_expr([collapse, Term], Goals, Result),
( silent(true) -> true ; format("\e[33m--> metta runnable -->~n\e[36m!~w~n\e[33m--> prolog goal -->\e[35m ~n", [FormStr]),
forall(member(G, Goals), portray_clause((:- G))),
format("\e[33m^^^^^^^^^^^^^^^^^^^^^^^~n\e[0m") ),
call_goals(Goals).
process_form(Space, parsed(function, FormStr, Term), []) :- add_sexp(Space, Term),
translate_clause(Term, Clause),
assertz(Clause, Ref),
assertz(translated_from(Ref, Term)),
( silent(true) -> true ; format("\e[33m--> metta function -->~n\e[36m~w~n\e[33m--> prolog clause -->~n\e[32m", [FormStr]),
clause(Head, Body, Ref),
( Body == true -> Show = Head; Show = (Head :- Body) ),
portray_clause(current_output, Show),
format("\e[33m^^^^^^^^^^^^^^^^^^^^^^~n\e[0m") ).
process_form(_, In, _) :- format(atom(Msg), "failed to process form: ~w", [In]), throw(error(syntax_error(Msg), none)).
% Process form for compilation: return goals to be placed in main/0
process_form_for_compile(Space, parsed(expression, _, Term), Goals) :-
Goals = ['add-atom'(Space, Term, true)].

process_form_for_compile(_, parsed(runnable, FormStr, Term), Goals) :-
translate_expr([collapse, Term], false, TranslatedGoals, Result),
% Convert goals list to conjunction
list_to_conjunction(TranslatedGoals, GoalsConj),
% Wrap in a goal that collects results and appends to accumulator
% We flatten the results to avoid nested lists
Goals = [findall(Result, GoalsConj, ResultsList),
flatten(ResultsList, FlatResults),
nb_getval(all_results, PrevResults),
append(PrevResults, FlatResults, NewResults),
nb_setval(all_results, NewResults)],
debug_print_goals(TranslatedGoals, FormStr).

process_form_for_compile(Space, parsed(function, FormStr, Term), Goals) :-
Goals = ['add-atom'(Space, Term, _)],
( silent(false) ->
translate_clause(Term, Clause),
clause(Clause, Body),
( Body == true -> Show = Clause; Show = (Clause :- Body) ),
format("\e[33m--> metta function -->~n\e[36m~w~n\e[33m--> prolog clause -->~n\e[32m", [FormStr]),
portray_clause(Show),
format("\e[33m^^^^^^^^^^^^^^^^^^^^^^~n\e[0m")
; true).

% Second pass to run / add the Terms.
% Output will contain the compilation output as a result.
% The goals are run and return in Results.
process_form(Space, parsed(expression, _, Term), [], Output) :-
( silent(false) ->
swrite(Term, STerm),
format("\e[33m--> metta sexpr -->~n\e[36m~w~n", [STerm]),
format("\e[33m^^^^^^^^^^^^^^^^^^^~n\e[0m")
; true),
'add-atom'(Space, Term, true),
with_output_to(string(Output), portray_clause(:- 'add-atom'(Space, Term, true))).

% We need to call the goals. We also don't need to include print
% statements in the translations, as we will print the Result later on.
process_form(_, parsed(runnable, FormStr, Term), Result, Output) :-
translate_expr([collapse, Term], true, Goals, Result),
call_goals(Goals),
write_to_output(Goals, Output),
debug_print_goals(Goals, FormStr).

process_form(Space, parsed(function, FormStr, Term), [], Output) :-
translate_clause(Term, Clause),
assertz(Clause, Ref),
assertz(translated_from(Ref, Term)),
clause(Head, Body, Ref),
% Just output the clause statically
( Body == true -> Show = Head; Show = (Head :- Body) ),
with_output_to(string(Output), portray_clause(Show)),
( silent(false) ->
format("\e[33m--> metta function -->~n\e[36m~w~n\e[33m--> prolog clause -->~n\e[32m", [FormStr]),
write(current_output, Output),
format("\e[33m^^^^^^^^^^^^^^^^^^^^^^~n\e[0m")
; true),
add_sexp(Space, Term).

process_form(_, In, _, _) :-
format(atom(Msg), "failed to process form: ~w", [In]),
throw(error(syntax_error(Msg), none)).

write_to_output(Goals, Output) :-
findall(
GoalOutput,
(member(G, Goals), with_output_to(string(GoalOutput), portray_clause((:- G)))),
GoalOutputs),
atomic_list_concat(GoalOutputs, Output).

debug_print_goals(Goals, FormStr) :-
(silent(false) ->
format("\e[33m--> metta runnable -->~n\e[36m!~w~n\e[33m--> prolog goal -->\e[35m ~n", [FormStr]),
forall(member(G, Goals), portray_clause((:- G))),
format("\e[33m^^^^^^^^^^^^^^^^^^^^^^^~n\e[0m")
; true).

% Build the main/0 predicate from all goals
build_main_predicate(GoalsList, MainClause) :-
% Flatten the list of goal lists into a single list
append(GoalsList, AllGoals),
% Add goal to print all collected results at the end
% We'll collect results using a global variable pattern
PrintGoal = (nb_getval(all_results, AllResults), forall(member(R, AllResults), writeln(R))),
InitGoal = nb_setval(all_results, []),
% Combine: initialize, run all goals, print results
append([[InitGoal], AllGoals, [PrintGoal]], FinalGoals),
% Create the main clause body
list_to_conjunction(FinalGoals, MainBody),
% Format as a clause
MainPredicate = (main :- MainBody),
with_output_to(string(MainClause), portray_clause(MainPredicate)).

% Helper to convert list of goals to conjunction
list_to_conjunction([], true).
list_to_conjunction([G], G) :- !.
list_to_conjunction([G|Gs], (G, Rest)) :- list_to_conjunction(Gs, Rest).

% Collect specialized function goals for compilation output
% This finds all specialized functions that were generated and returns goals to assert them
collect_specialization_goals(Goals) :-
ho_specialization(_, SpecName),
% Find a clause for this specialized function
current_predicate(SpecName/Arity),
functor(Head, SpecName, Arity),
clause(Head, Body, Ref),
% Verify this clause was created by the specializer and get its source term
translated_from(Ref, SourceTerm),
% Return goals that register the function, assert clause and mapping
( Body == true -> Show = Head ; Show = (Head :- Body) ),
Goals = [register_fun(SpecName), assertz(Show, R), assertz(translated_from(R, SourceTerm))].



%Like blanks but counts newlines:
newlines(C0, C2) --> blanks_to_nl, !, {C1 is C0+1}, newlines(C1,C2).
Expand Down
Loading