From c812829660be8dad6c4a9e9d79a83accf2b832f0 Mon Sep 17 00:00:00 2001 From: TeamSPoon Date: Sat, 13 Jan 2024 20:32:09 -0800 Subject: [PATCH] debugging/debug_some.mettarc --- MeTTa | 217 ++++++++++-------- examples/features/debugging/debug_none.metta | 0 .../features/debugging/debug_some.mettarc | 6 + .../features/debugging/debug_some_more.metta | 0 .../hyperon_experimental_issue_481.metta | 33 +++ .../hyperon_experimental_issue_492.metta | 17 ++ .../hyperon_experimental_issue_500.metta | 15 ++ .../hyperon_experimental_issue_514.metta | 17 ++ .../hyperon_experimental_issue_516.metta | 44 ++++ ...eron_experimental_issue_516_redduced.metta | 9 + .../hyperon_experimental_issue_530.metta | 27 +++ metta_vspace/pyswip/metta_data.pl | 2 + metta_vspace/pyswip/metta_eval.pl | 26 ++- metta_vspace/pyswip/metta_interp.pl | 50 ++-- metta_vspace/pyswip/metta_printer.pl | 8 +- metta_vspace/pyswip/metta_reader.pl | 25 +- metta_vspace/pyswip/metta_server.pl | 43 +++- metta_vspace/pyswip/metta_utils.pl | 3 + metta_vspace/pyswip/swi_support.pl | 4 +- 19 files changed, 395 insertions(+), 151 deletions(-) create mode 100644 examples/features/debugging/debug_none.metta create mode 100755 examples/features/debugging/debug_some.mettarc create mode 100644 examples/features/debugging/debug_some_more.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_481.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_492.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_500.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_514.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_516.metta create mode 100755 examples/features/debugging/hyperon_experimental_issue_516_redduced.metta create mode 100644 examples/features/debugging/hyperon_experimental_issue_530.metta diff --git a/MeTTa b/MeTTa index 1405b5f9..542193c1 100755 --- a/MeTTa +++ b/MeTTa @@ -12,6 +12,7 @@ should_compile=0 never_compile=0 CMD_TIMEOUT=0 repl_flag=enable +use_rc_file=~/.mettalogrc # Initialize the variable to indicate whether to use the test script use_test_script=0 @@ -41,9 +42,10 @@ fi set -e -function load_mettalogrc { - local file="${1:-$HOME/.mettalogrc}" # Use the argument if supplied, else use the default file - local METTALOG_OPTIONS=() + +function load_rc_file { + local file="$1" # Use the argument as the file + local METTALOG_OPTIONS_LOCAL=() local multiline_accumulator="" local verbose="${VERBOSE:-0}" # Use the VERBOSE environment variable or default to '0' (not verbose) @@ -66,23 +68,20 @@ function load_mettalogrc { [[ $line =~ ^# ]] && continue # Skip lines that start with a comment - METTALOG_OPTIONS+=("$line") + METTALOG_OPTIONS_LOCAL+=("$line") # Verbose logging [[ "$verbose" == "1" ]] && echo "Loaded option: $line" done < "$file" - else - [[ "$verbose" == "1" ]] && echo "File $file does not exist." - return 1 fi - # Return the array (in bash, arrays are typically returned by echoing their elements) - echo "${METTALOG_OPTIONS[@]}" - return 0 + local do_args="${METTALOG_OPTIONS_LOCAL[@]}" + [[ -z "$do_args" ]] && return + echo "handle_args ${do_args}" + handle_args "${do_args}" } - add_to_list() { local item="$1" local -n list_ref="$2" @@ -92,76 +91,83 @@ add_to_list() { } function print_help { - echo " Usage: $0 [options] ... [-- arg ...passed to your program...]" + echo " Usage: ${MeTTa} [options] ... [-- arg ...passed to your program...]" echo " $0 --help Display this message" echo " $0 --version Display version information" - echo "" - echo " -x state Start from state (must be first)" - echo " -g goal Run goal (may be repeated)" - echo " -t toplevel Toplevel goal" - echo " -f file User initialisation file" - echo " -F file Site initialisation file" - echo " -l file Script source file" - echo " -s file Script source file" - echo " -p alias=path Define file search path 'alias'" - echo " " - echo " Compilation: " - echo "" - echo " $0 [options] [-o executable] -c metta-file1 -c metta-file2 ... to compile into executable ..." - echo "" - echo " -O Optimised compilation" - echo " --debug[=bool] Do (not) generate debug info" - echo " --traditional Disable extensions of version (SWI-Prolog version 7)" - echo " --abi-version Display ABI version key (and exit)" - echo " --arch Display architecture (and exit)" - echo " --dump-runtime-variables[=format] " - echo " Dump link info in sh(1) format (and exit)" - echo "" - echo " Running:" - echo " --repl Start the REPL (Read-Eval-Print Loop) after processing metta files." - echo " If no metta files are provided, this is the default behavior." - echo " --home[=DIR] Print home or use DIR as SWI-Prolog home" - echo " --stack-limit=size[BKMG] Specify maximum size of stacks" - echo " --table-space=size[BKMG] Specify maximum size of SLG tables" - echo " --shared-table-space=size[BKMG] Maximum size of *shared* SLG tables" - echo " --pce[=bool] Make the xpce gui available" - echo " --packs[=bool] Do (not) attach add-ons" - echo " --pldoc[=port] Start PlDoc server [at port]" - echo " --python[=bool] Enable or disable Python support (default: $python_flag)" - echo " --tty[=bool] (Dis)allow tty control" - echo " --quiet[=bool] (-q) Do (not) suppress informational messages" - echo " " - echo " Testing:" - echo " --test Use the test options:" - echo " --continue Continue running tests (Generating any missing html files)" - echo " --failures Rerun unsuccessfull tests only" - echo " --timeout=seconds Kill the script after so many seconds." - echo " --html[=bool] Save an HTML file containing terminal output in the same" - echo " directory as the input file or directory." - echo " Defaults to true if exactly one metta file or directory argument was provided" - echo " --fresh Clean up by deleting any .answers files under directory" - echo " --clean Clean up by deleting all .html files under directory" - echo " " - echo " Debugging:" - echo " --exec=skip Skip over !exec dirrectives" - echo " --eval=rtrace Recursively trace Evaluation" - echo " --signals[=bool] Do (not) modify signal handling" - echo " --threads[=bool] Do (not) allow for threads" - echo " --debug-on-interrupt[=bool] Trap the debugger on interrupt" - echo " --prolog Drop to the host system debugger" - echo " --on-error=style One of print, halt or status" - echo " --on-warning=style One of print, halt or status" - echo "" - echo " Boolean options may be written as --name=bool, --name, --no-name or --noname." - echo " Both '-' or '_' are accepted as word-separator for long options." - echo "" - echo " Configuration File:" - echo " This script reads options from the ~/.mettalogrc file, one option per line." - echo " Options specified in ~/.mettalogrc are processed before command-line arguments." - echo "" - echo " WAS: $0 ${SWI_OPTIONS[*]} -l $METTALOG_DIR/metta_vspace/$PYSWIP_VERSION/metta_interp.pl -- --python=$python_flag ${PRE_METTALOG_OPTIONS[*]} ${METTALOG_OPTIONS[*]} \\" - echo " $METTA_CMD" - echo "" +cat << EOF + + -x state Start from state (must be first) + -g goal Run goal (may be repeated) + -t toplevel Toplevel goal + -f file User initialisation file + -F file Site initialisation file + -l file Script source file + -s file Script source file + -p alias=path Define file search path 'alias' + + Compilation: + + ${MeTTa} [options] [-o executable] -c metta-file1 -c metta-file2 ... to compile into executable ... + + -O Optimised compilation + --debug[=bool] Do (not) generate debug info + --traditional Disable extensions of version (SWI-Prolog version 7) + --abi-version Display ABI version key (and exit) + --arch Display architecture (and exit) + --dump-runtime-variables[=format] + Dump link info in sh(1) format (and exit) + + Running: + --rc File read command line arguments from a file + --repl Start the REPL (Read-Eval-Print Loop) after processing metta files. + If no metta files are provided, this is the default behavior. + --home[=DIR] Print home or use DIR as SWI-Prolog home + --stack-limit=size[BKMG] Specify maximum size of stacks + --table-space=size[BKMG] Specify maximum size of SLG tables + --shared-table-space=size[BKMG] Maximum size of *shared* SLG tables + --pce[=bool] Make the xpce gui available + --packs[=bool] Do (not) attach add-ons + --pldoc[=port] Start PlDoc server [at port] + --python[=bool] Enable or disable Python support (default: $python_flag) + --tty[=bool] (Dis)allow tty control + --quiet[=bool] (-q) Do (not) suppress informational messages + + Testing: + --test Use the test options: + --continue Continue running tests (Generating any missing html files) + --failures Rerun unsuccessfull tests only + --regressions Rerun only tests in which we previously scored 100% + + --timeout=seconds Kill the script after so many seconds. + --html[=bool] Save an HTML file containing terminal output in the same + directory as the input file or directory. + Defaults to true if exactly one metta file or directory argument was provided + --fresh Clean up by deleting any .answers files under directory + --clean Clean up by deleting all .html files under directory + + Debugging: + --exec=skip Skip over !exec dirrectives + --eval=debug Recursively trace Evaluation + --case=debug Show extra debug info about case statements + --signals[=bool] Do (not) modify signal handling + --threads[=bool] Do (not) allow for threads + --debug-on-interrupt[=bool] Trap the debugger on interrupt + --prolog Drop to the host system debugger + --on-error=style One of print, halt or status + --on-warning=style One of print, halt or status + + Boolean options may be written as --name=bool, --name, --no-name or --noname. + Both '-' or '_' are accepted as word-separator for long options. + + Configuration File: + This script reads options from the ~/.mettalogrc file, one option per line. + Options specified in ~/.mettalogrc are processed before command-line arguments. + + WAS: $0 ${SWI_OPTIONS[*]} -l $METTALOG_DIR/metta_vspace/$PYSWIP_VERSION/metta_interp.pl -- --python=$python_flag ${PRE_METTALOG_OPTIONS[*]} ${METTALOG_OPTIONS[*]} \\ + $METTA_CMD + + +EOF } @@ -187,9 +193,20 @@ function handle_args { SWI_FLAG_WITH_ARG=false METTA_FLAG_WITH_ARG=false SKIP_TO_METTALOG_OPTIONS=false + NEXT_ARG_IS_RC_FILE=false + PrevDir="${RPWD:-$(pwd)}" # Default to current directory if PrevDir is not set for arg in "$@"; do + # Check if the previous argument was --rc + if [[ "$NEXT_ARG_IS_RC_FILE" == true ]]; then + rc_file_path="$PrevDir/$arg" # Resolve file path relative to PrevDir + rc_file_path="$(realpath "$rc_file_path")" # Resolve to absolute path + load_rc_file "$rc_file_path" + NEXT_ARG_IS_RC_FILE=false + continue + fi + if [[ $SKIP_TO_METTALOG_OPTIONS == true ]]; then METTALOG_OPTIONS+=("$arg") continue @@ -201,6 +218,12 @@ function handle_args { continue fi + # Add support for --rc followed by a file + if [[ "$arg" == "--rc" ]]; then + NEXT_ARG_IS_RC_FILE=true + continue + fi + arg=$(remove_quotes "$arg") # Remove the quotes # track file paths but keep going @@ -291,8 +314,9 @@ function handle_args { done } + # First process arguments from ~/.mettalogrc -handle_args $(load_mettalogrc) + # Then process actual command-line arguments #handle_args "$@" @@ -304,9 +328,14 @@ for arg in "$@"; do if [[ -f "$arg_realpath" || -d "$arg_realpath" ]]; then add_to_list "$arg_realpath" LIST_OF_FILE_ARGS fi + elif [[ "$arg" =~ ^--rc=(.*) ]]; then + use_rc_file="" + continue fi done +# Then process actual command-line arguments + #echo "LIST_OF_FILE_ARGS[0]=${LIST_OF_FILE_ARGS[0]}" DIRNAME="${LIST_OF_FILE_ARGS[0]}" if [[ -f "$DIRNAME" ]]; then @@ -320,31 +349,21 @@ else fi DIR_RC="$DIRNAME/.mettalogrc" #echo "DIR_RC=$DIR_RC" -if [[ -f "$DIR_RC" ]]; then - DIR_OPTS=$(load_mettalogrc "$DIR_RC") - echo "DIR_RC($DIR_RC)='$DIR_OPTS'" - # Assuming DIR_OPTS contains options and not filenames. - # So we directly handle them as arguments. - if [[ ! -z "$DIR_OPTS" ]]; then - handle_args $DIR_OPTS - fi +if [[ -z "${use_rc_file}" ]]; then + : +elif [[ -f "$DIR_RC" ]]; then + use_rc_file="${DIR_RC}" else - echo ";" echo "; No RC file (.mettalogrc) for directory: $DIRNAME" - echo ";" -fi - -# Then process actual command-line arguments - -if [[ ! -z "$DIR_OPTS" ]]; then - handle_args $DIR_OPTS fi handle_args "$@" +load_rc_file $use_rc_file -#echo "Debug: SWI_OPTIONS: ${SWI_OPTIONS[@]}" -#echo "Debug: LIST_OF_FILE_ARGS: ${LIST_OF_FILE_ARGS[@]}" -#echo "Debug: METTALOG_OPTIONS: ${METTALOG_OPTIONS[@]}" +echo "Debug: SWI_OPTIONS: ${SWI_OPTIONS[@]}" +echo "Debug: PRE_METTALOG_OPTIONS: ${PRE_METTALOG_OPTIONS[@]}" +echo "Debug: LIST_OF_FILE_ARGS: ${LIST_OF_FILE_ARGS[@]}" +echo "Debug: METTALOG_OPTIONS: ${METTALOG_OPTIONS[@]}" # Decide on enabling the REPL if [[ "$repl_flag" == "enable" ]]; then diff --git a/examples/features/debugging/debug_none.metta b/examples/features/debugging/debug_none.metta new file mode 100644 index 00000000..e69de29b diff --git a/examples/features/debugging/debug_some.mettarc b/examples/features/debugging/debug_some.mettarc new file mode 100755 index 00000000..c1ae9690 --- /dev/null +++ b/examples/features/debugging/debug_some.mettarc @@ -0,0 +1,6 @@ +--load=debug +# --exec=skip +--exec=debug +--eval=debug +--case=debug + diff --git a/examples/features/debugging/debug_some_more.metta b/examples/features/debugging/debug_some_more.metta new file mode 100644 index 00000000..e69de29b diff --git a/examples/features/debugging/hyperon_experimental_issue_481.metta b/examples/features/debugging/hyperon_experimental_issue_481.metta new file mode 100755 index 00000000..0caa3c5a --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_481.metta @@ -0,0 +1,33 @@ +; https://github.com/trueagi-io/hyperon-experimental/issues/481 + +;patham9 commented on Nov 1, 2023 • +;Clearly there is no way for the following collapse to have any item: + +!(== () (collapse (let* (($L ()) + ($x (superpose $L))) + $x))) +;Yet: +;Output: [False] +;Expected: [True] + +;MeTTa leaves the let* expression unevaluated in this case, which leaves the collapse with a "pseudo-item", an expression with variables, which leads to the comparison to return false even though there cannot be any variable assignment that actually satisfies the let* expression. + + +; vsbogd commented on Nov 2, 2023 + + +;Regarding minimal MeTTa, we have Empty symbol there to represent an empty result. Using it we could potentially properly fix superpose to return Empty from (superpose Empty) call. Thus the example above will turn into: +!(collapse (let $L Empty (let $x (superpose $L) $x))) + + +;And collapse will return () in this case. One can "simulate" this on a current version of minimal MeTTa using additional parenthesis: +!(collapse (let $L (Empty) (let $x (superpose $L) $x))) + +; vsbogd commented on Nov 2, 2023 +; Thus if (superpose $T) is called with $T == Empty it will work. We should also fix collapse to return Empty instead of () to make it complete and allow collapse/superpose chains on Empty results. + +; patham9 commented on Nov 6, 2023 +; I didn't yet get why "Empty" needs to be an explicit value. Either there is a value, which can be an empty tuple () or 42 as a special case, or there is no value, in which case backtracking should occur. What is it for? + + + diff --git a/examples/features/debugging/hyperon_experimental_issue_492.metta b/examples/features/debugging/hyperon_experimental_issue_492.metta new file mode 100755 index 00000000..e6aa4fa6 --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_492.metta @@ -0,0 +1,17 @@ + + +; https://github.com/trueagi-io/hyperon-experimental/issues/492 + + +(= (memb $X Nil) False) +(= (memb $X (Cons $H $Tail)) + (memb $X $Tail)) +(= (memb $X (Cons $X $Tail)) + True) + + +!(let $res + (and (memb $X (Cons 1 (Cons 2 Nil))) + (memb $X (Cons 2 (Cons 3 Nil)))) + (if $res $X None)) + diff --git a/examples/features/debugging/hyperon_experimental_issue_500.metta b/examples/features/debugging/hyperon_experimental_issue_500.metta new file mode 100755 index 00000000..fb9c2f64 --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_500.metta @@ -0,0 +1,15 @@ + +; https://github.com/trueagi-io/hyperon-experimental/issues/500 + + +(: all (-> Atom Bool)) +(= (all $A) + (if (== () $A) True + (if (car-atom $A) + (let $cdr (cdr-atom $A) (all $cdr)) + False) + ) +) + +(= (loop) (loop)) +!(all (True False (loop) True)) diff --git a/examples/features/debugging/hyperon_experimental_issue_514.metta b/examples/features/debugging/hyperon_experimental_issue_514.metta new file mode 100755 index 00000000..29ce24c1 --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_514.metta @@ -0,0 +1,17 @@ + + +; https://github.com/trueagi-io/hyperon-experimental/issues/514 + +(= (loop) (loop)) + +; instead we can rewrite and via if + +(: and2 (-> Atom Atom Bool)) +(= (and2 $X $Y) + (if $X $Y False)) + +!(and2 False (loop)) + +!(and False (loop)) +; Evaluating the second argument will harm the performance even if the second argument doesn't contain infinite loop + diff --git a/examples/features/debugging/hyperon_experimental_issue_516.metta b/examples/features/debugging/hyperon_experimental_issue_516.metta new file mode 100755 index 00000000..66ac9836 --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_516.metta @@ -0,0 +1,44 @@ +; https://github.com/trueagi-io/hyperon-experimental/issues/516 + + + +;; Example usage in the Pattern Miner work, + +;; Define List +(: List (-> $a Type)) +(: Cons (-> $a (List $a) (List $a))) +(: Nil (List $a)) + +;; Define DeBruijn Index +(: DeBruijn Type) +(: VarIdx (-> Nat DeBruijn)) + +;; Map a DeBruijn Index to an given variable +(: idx2var (-> DeBruijn (List Variable) Atom)) +(= (idx2var (VarIdx Z) (Cons $head $tail)) $head) +(= (idx2var (VarIdx (S $k)) (Cons $head $tail)) (idx2var (VarIdx $k) $tail)) + +;; Map a DeBruijn Index in a given pattern to a variable +(: Debruijn2var (-> Atom (List Variable) Atom)) +(= (Debruijn2var (VarIdx $k) $varlist) + (idx2var (VarIdx $k) $varlist)) + +(= (Debruijn2var $symbol $varlist) + (if (== (get-type $symbol) %Undefined%) $symbol (empty))) + +(= (Debruijn2var ($link $first $second) $varlist) + ($link (Debruijn2var $first $varlist) (Debruijn2var $second $varlist))) + + +;; The Debruijn index here is used to wrap the MeTTa Variables to make it easy for the synthesizer to do the unification. +;; And during the match query, we unwrap them to variables and Debruijn2var function above is doing that. + +!(, (Debruijn2var (Inheritance (VarIdx Z) human) (Cons $Xvar (Cons $Yvar Nil))) + (Debruijn2var (Inheritance (VarIdx Z) man) (Cons $Xvar (Cons $Yvar Nil)))) + +;returns +;[(, (Inheritance $Xvar human) (Inheritance $X#311 man))] +; Expected result, to be able to do pattern matching is, +;[(, (Inheritance $Xvar human) (Inheritance $Xvar man))] + + diff --git a/examples/features/debugging/hyperon_experimental_issue_516_redduced.metta b/examples/features/debugging/hyperon_experimental_issue_516_redduced.metta new file mode 100755 index 00000000..a7cf0f5a --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_516_redduced.metta @@ -0,0 +1,9 @@ + +;; Define foo +(: foo (-> Atom Variable Atom)) +(= (foo Z $var) $var) +(= (foo (R Z) $var) (R (foo Z $var))) + +;; Test foo +!(foo Z $a) ;; returns [$a] that's expected result, but +!(foo (R Z) $a) ;; returns [(R $X#19)] instead of [(R $a)] diff --git a/examples/features/debugging/hyperon_experimental_issue_530.metta b/examples/features/debugging/hyperon_experimental_issue_530.metta new file mode 100644 index 00000000..64479dd3 --- /dev/null +++ b/examples/features/debugging/hyperon_experimental_issue_530.metta @@ -0,0 +1,27 @@ +; from https://github.com/trueagi-io/hyperon-experimental/issues/530 +; What is the problem? +; Unification such as (A $a $a) ≐ (A $x $y) fails to recognize that $x = $y. + +; How to reproduce the problem? +; Run the following metta code + + +(A $a $a) +!(match &self (A $x $y) (A $x $y)) + +;;What should be normally output? +;;It should output (A $x $x) or (A $y $y) (or even (A $a $a) if the variables present in the query are not prioritized). + +;;What is output instead? +;;(A $x $y) + +!(repl!) + + +;What else can you tell? +;When variable $a is replaced by a, as in + +(AA a a) +!(match &self (AA $x $y) (AA $x $y)) + + diff --git a/metta_vspace/pyswip/metta_data.pl b/metta_vspace/pyswip/metta_data.pl index 60937771..68aa0151 100755 --- a/metta_vspace/pyswip/metta_data.pl +++ b/metta_vspace/pyswip/metta_data.pl @@ -4,6 +4,8 @@ is_syspred0(H,_Ln,_Prd):- upcase_atom(H,U),downcase_atom(H,U),!,fail. is_syspred0(H,Len,Pred):- current_predicate(H/Len),!,Pred=H. is_syspred0(H,Len,Pred):- atom_concat(Mid,'!',H), H\==Mid, is_syspred0(Mid,Len,Pred),!. +is_syspred0(H,Len,Pred):- atom_concat(Mid,'-p',H), H\==Mid, is_syspred0(Mid,Len,Pred),!. +is_syspred0(H,Len,Pred):- atom_concat(Mid,'-fn',H), H\==Mid, is_syspred0(Mid,Len,Pred),!. is_syspred0(H,Len,Pred):- into_underscores(H,Mid), H\==Mid, is_syspred0(Mid,Len,Pred),!. %is_function(F):- atom(F). is_metta_data_functor(_Eq,_Othr,H):- clause(is_data_functor(H),_). diff --git a/metta_vspace/pyswip/metta_eval.pl b/metta_vspace/pyswip/metta_eval.pl index 13154a60..ccd56bdd 100755 --- a/metta_vspace/pyswip/metta_eval.pl +++ b/metta_vspace/pyswip/metta_eval.pl @@ -804,6 +804,9 @@ eval_20(Eq,RetType,Depth,Self,['Cons', A, B ],['Cons', AA, BB]):- no_cons_reduce, !, eval(Eq,RetType,Depth,Self,A,AA), eval(Eq,RetType,Depth,Self,B,BB). +eval_20(_Eq,_RetType,Depth,Self,['::'|PL],Prolog):- maplist(as_prolog(Depth,Self),PL,Prolog),!. +eval_20(_Eq,_RetType,Depth,Self,['@'|PL],Prolog):- as_prolog(Depth,Self,['@'|PL],Prolog),!. + eval_20(Eq,RetType,Depth,Self,['Cons', A, B ],[AA|BB]):- \+ no_cons_reduce, !, eval(Eq,RetType,Depth,Self,A,AA), eval(Eq,RetType,Depth,Self,B,BB). @@ -1168,7 +1171,8 @@ suggest_type(_RetType,_Bool). -eval_40(Eq,RetType,Depth,Self,[AE|More],Res):- fail, %is_special_op(AE),!, +eval_40(Eq,RetType,Depth,Self,[AE|More],Res):- + is_special_op(AE),!, eval_70(Eq,RetType,Depth,Self,[AE|More],Res), check_returnval(Eq,RetType,Res). @@ -1204,13 +1208,16 @@ % ================================================================= % ================================================================= is_system_pred(S):- atom(S),atom_concat(_,'!',S). +is_system_pred(S):- atom(S),atom_concat(_,'-fn',S). +is_system_pred(S):- atom(S),atom_concat(_,'-p',S). +:- discontiguous eval_80/6. %eval_80(_Eq,_RetType,_Dpth,_Slf,LESS,Res):- notrace((once((eval_selfless(LESS,Res),notrace(LESS\==Res))))),!. % predicate inherited by system -eval_80(Eq,RetType,_Depth,_Self,[AE|More],TF):- +eval_80(Eq,RetType,Depth,Self,[AE|More],TF):- once((is_system_pred(AE), length(More,Len), is_syspred(AE,Len,Pred))), @@ -1218,7 +1225,7 @@ current_predicate(Pred/Len), %notrace( \+ is_user_defined_goal(Self,[AE|More])),!, %adjust_args(Depth,Self,AE,More,Adjusted), - More = Adjusted, + maplist(as_prolog(Depth,Self),More,Adjusted), catch_warn(efbug(show_call,eval_call(apply(Pred,Adjusted),TF))), check_returnval(Eq,RetType,TF). @@ -1227,8 +1234,6 @@ :- if( \+ current_predicate( adjust_args / 2 )). - :- discontiguous eval_80/6. - is_user_defined_goal(Self,Head):- is_user_defined_head(Self,Head). @@ -1263,16 +1268,15 @@ s2ps(S,P), !, fbug(eval_call(P,'$VAR'('TF'))),as_tf(P,TF). -eval_80(Eq,RetType,_Depth,_Self,[AE|More],Res):- +eval_80(Eq,RetType,Depth,Self,[AE|More],Res):- is_system_pred(AE), - length([AE|More],Len), - is_syspred(AE,Len,Pred), + is_syspred(AE,_,Pred), \+ (atom(AE), atom_concat(_,'-p',AE)), %notrace( \+ is_user_defined_goal(Self,[AE|More])),!, %adjust_args(Depth,Self,AE,More,Adjusted),!, - More = Adjusted, - Len1 is Len+1, - current_predicate(Pred/Len1), + length([AE|More],Len), + current_predicate(Pred/Len), + maplist(as_prolog(Depth,Self),More,Adjusted), append(Adjusted,[Res],Args),!, efbug(show_call,catch_warn(apply(Pred,Args))), check_returnval(Eq,RetType,Res). diff --git a/metta_vspace/pyswip/metta_interp.pl b/metta_vspace/pyswip/metta_interp.pl index 7a376c12..8df6c847 100755 --- a/metta_vspace/pyswip/metta_interp.pl +++ b/metta_vspace/pyswip/metta_interp.pl @@ -79,15 +79,18 @@ option_value_def('trace-on-error',true). -%option_value_def('trace-on-load',false). +option_value_def('trace-on-load',true). +option_value_def('load',debug). option_value_def('trace-on-exec',true). option_value_def('trace-on-eval',true). option_value_def('trace-on-fail',false). option_value_def('trace-on-pass',false). - +set_option_value_interp(N,V):- atom(N), atomic_list_concat(List,',',N),List\=[_],!, + forall(member(E,List),set_option_value_interp(E,V)). set_option_value_interp(N,V):- set_option_value(N,V), + fbug(set_option_value(N,V)), ignore((if_t((atom(N), atom_concat('trace-on-',F,N)),set_debug(F,V)))), ignore((if_t((atom(V), is_debug_like(V)),set_debug(N,true)))),!. @@ -99,8 +102,8 @@ forall(option_value_def(A,B),set_option_value_interp(A,B)), set_option_value_interp('trace-on-pass',false), set_option_value_interp('trace-on-fail',false), - if_t(TF,set_option_value_interp('exec',rtrace)), - if_t(TF,set_option_value_interp('eval',rtrace)), + if_t(TF,set_option_value_interp('exec',debug)), + if_t(TF,set_option_value_interp('eval',debug)), set_option_value_interp('trace-on-load',TF), set_option_value_interp('trace-on-exec',TF), set_option_value_interp('trace-on-eval',TF), @@ -334,9 +337,9 @@ cmdline_load_metta(Self,[M|Rest]):- m_opt(M,Opt),!, - is_cmd_option(Opt,M,TF),!, - fbug(is_cmd_option(Opt,M,TF)), !, set_option_value_interp(Opt,TF), - set_tty_color_term(true), + forall((is_cmd_option(Opt,M,TF)), + (fbug(is_cmd_option(Opt,M,TF)), !, set_option_value_interp(Opt,TF))), + %set_tty_color_term(true), cmdline_load_metta(Self,Rest). cmdline_load_metta(Self,[M|Rest]):- @@ -488,7 +491,7 @@ write_f_src(HB):- hb_f(HB,ST), option_else(current_def,CST,[]),!, - (CST == ST -> true ; (nl,nl,nl,set_option_value_interp(current_def,ST))), + (CST == ST -> true ; (nl,nl,nl,set_option_value(current_def,ST))), write_src(HB). @@ -592,7 +595,7 @@ repl_read(Str,Atom):- atom_string(Atom,Str),metta_interp_mode(Atom,_),!. repl_read(Str, Expr):- atom_concat('@',_,Str),!,atom_string(Expr,Str). -repl_read(Str, Expr):- atom_concat(')',_,Str),!,fbug(repl_read_syntax(Str)),throw(restart_reading). +repl_read(Str, _Expr):- atom_concat(')',_,Str),!,fbug(repl_read_syntax(Str)),throw(restart_reading). repl_read(NewAccumulated, Expr):- normalize_space(string(Renew),NewAccumulated), Renew \== NewAccumulated, !, @@ -769,8 +772,11 @@ trly(_,A,A). mfix_vars1(I,O):- var(I),!,I=O. -mfix_vars1('$t','$VAR'('T')):-!. -mfix_vars1('$T','$VAR'('T')):-!. +mfix_vars1('$_','$VAR'('_')). +mfix_vars1('$','$VAR'('__')). +mfix_vars1(I,'$VAR'(O)):- atom(I),atom_concat('$',N,I),atom_concat('_',N,O). +%mfix_vars1('$t','$VAR'('T')):-!. +%mfix_vars1('$T','$VAR'('T')):-!. %mfix_vars1(I,O):- I=='T',!,O='True'. %mfix_vars1(I,O):- I=='F',!,O='False'. %mfix_vars1(I,O):- is_i_nil(I),!,O=[]. @@ -796,7 +802,6 @@ mfix_vars1(I,O):- compound(I),!,compound_name_arguments(I,F,II),F\=='$VAR',maplist(mfix_vars1,II,OO),!,compound_name_arguments(O,F,OO). mfix_vars1(I,O):- \+ atom(I),!,I=O. -mfix_vars1(I,'$VAR'(O)):- atom_concat('$',N,I),dvar_name(N,O),!. mfix_vars1(I,I). no_cons_reduce. @@ -805,11 +810,14 @@ %dvar_name(t,'T'):- !. +dvar_name(N,O):-atom_concat('_',_,N),!,O=N. dvar_name(N,O):- integer(N),atom_concat('_',N,O). dvar_name(N,O):- atom(N),atom_number(N,Num),dvar_name(Num,O),!. dvar_name(N,O):- \+ atom(N),!,format(atom(A),'~w',[N]),dvar_name(A,O). -dvar_name('','__'):-!. % "$" -dvar_name('_','_'):-!. % "$_" +dvar_name(N,O):- !, format(atom(A),'_~w',[N]),dvar_name(A,O). +%dvar_name( '',''):-!. % "$" +%dvar_name('_','__'):-!. % "$_" +dvar_name(N,O):-atom_concat('_',_,N),!,atom_concat('_',N,O). dvar_name(N,O):- svar_fixvarname_dont_capitalize(N,O),!. dvar_name(N,O):- must_det_ll((atom_chars(N,Lst),maplist(c2vn,Lst,NList),atomic_list_concat(NList,S),svar_fixvarname_dont_capitalize(S,O))),!. c2vn(A,A):- char_type(A,prolog_identifier_continue),!. @@ -1441,11 +1449,11 @@ current_read_mode(repl,Mode), %ignore(shell('stty sane ; stty echo')), %current_input(In), - format(atom(P2),'metta> ',[]), + %format(atom(P2),'metta> ',[]), format(atom(P),'metta ~w ~w> ',[Self, Mode]))), setup_call_cleanup( notrace(prompt(Was,P)), - notrace((write(P),ttyflush,repl_read(Expr),ttyflush)), + notrace((ttyflush,repl_read(Expr),ttyflush)), notrace(prompt(_,Was))), if_trace(replt,fbug(repl_read(Mode,Expr))), %fbug(repl_read(Expr)), @@ -1628,7 +1636,7 @@ (timed_call(GG,Seconds)), ((Complete==true->!;true), %repeat, - set_option_value_interp(interactive,WasInteractive), + set_option_value(interactive,WasInteractive), Control = contrl(Max,DoLeap), nb_setarg(1,Result,Output), read_pending_codes(user_input,_,[]), @@ -1874,6 +1882,8 @@ vu(trace,_Value):- trace. :- nodebug(metta(eval)). :- nodebug(metta(exec)). +:- nodebug(metta(load)). +:- nodebug(metta(prolog)). % Measures the execution time of a Prolog goal and displays the duration in seconds, % milliseconds, or microseconds, depending on the execution time. % @@ -2028,9 +2038,9 @@ pre_halt1:- is_compiling,!,fail. pre_halt1:- loonit_report,fail. pre_halt2:- is_compiling,!,fail. -pre_halt2:- option_value('prolog',true),!,set_option_value_interp('prolog',started),call_cleanup(prolog,pre_halt2). -pre_halt2:- option_value('repl',true),!,set_option_value_interp('repl',started),call_cleanup(repl,pre_halt2). -pre_halt2:- need_interaction, set_option_value_interp('had_interaction',true),call_cleanup(repl,pre_halt2). +pre_halt2:- option_value('prolog',true),!,set_option_value('prolog',started),call_cleanup(prolog,pre_halt2). +pre_halt2:- option_value('repl',true),!,set_option_value('repl',started),call_cleanup(repl,pre_halt2). +pre_halt2:- need_interaction, set_option_value('had_interaction',true),call_cleanup(repl,pre_halt2). %loon:- time(loon_metta('./examples/compat/test_scripts/*.metta')),fail. %loon:- repl, (option_value('halt',false)->true;halt(7)). diff --git a/metta_vspace/pyswip/metta_printer.pl b/metta_vspace/pyswip/metta_printer.pl index 43a6d060..70ed5d82 100755 --- a/metta_vspace/pyswip/metta_printer.pl +++ b/metta_vspace/pyswip/metta_printer.pl @@ -76,7 +76,13 @@ % Handling the final write when the value is a variable or a '$VAR' structure. is_final_write(V):- var(V), !, format('$~p',[V]). -is_final_write('$VAR'(S)):- !, write('$'),write(S). +is_final_write('$VAR'(S)):- S=='_', !, write('$'),write(S). +is_final_write('$VAR'(S)):- S=='__', !, write('$'). +is_final_write('$VAR'(S)):- var(S), write('$'),write(S). +is_final_write('$VAR'(S)):- number(S), write('$'),write(S). +is_final_write('$VAR'(S)):- atom(S), atom_concat('_',N,S),write('$'),write(N). +is_final_write('$VAR'(S)):- string(S), atom_concat('_',N,S),write('$'),write(N). + % Handling more cases for 'write_src1', when the value is a number, a string, a symbol, or a compound. write_src1(V) :- is_final_write(V),!. diff --git a/metta_vspace/pyswip/metta_reader.pl b/metta_vspace/pyswip/metta_reader.pl index f3d0d14b..37eff7d8 100755 --- a/metta_vspace/pyswip/metta_reader.pl +++ b/metta_vspace/pyswip/metta_reader.pl @@ -80,7 +80,7 @@ def_compile_all(I,O):- current_predicate(compile_all/2),!,call(call,compile_all,I,O). -def_compile_all(I,O):- wdmsg(undefined_compile_all(I)),I=O. +def_compile_all(I,O):- fbug(undefined_compile_all(I)),I=O. zalwayzz(G):- call(G)*->true;throw(fail_zalwayzz(G)). @@ -112,9 +112,9 @@ :- encoding(iso_latin_1). %string_metta(S) --> `"`, !, string_until_metta(S, `"`), {atomics_to_string_metta(A,S)}. %string_metta(Text) --> `"`, !, zalmetta_wayzz_metta(string_until_metta(Text,`"`)),!. -%string_metta(Text) --> `�`, !, zalmetta_wayzz_metta(string_until_metta(Text,(`�`;`�`))),!. +%string_metta(Text) --> `“`, !, zalmetta_wayzz_metta(string_until_metta(Text,(`”`;`“`))),!. string_metta(Text) --> (`"`), string_until_metta(L,(`"`)), {atomics_to_string(L,Text)}, !. -string_metta(Text) --> (`�`;`�`;`"`), !, string_until_metta(L,(`�`;`�`;`"`)), {atomics_to_string(L,Text)}. +string_metta(Text) --> (`”`;`“`;`"`), !, string_until_metta(L,(`“`;`”`;`"`)), {atomics_to_string(L,Text)}. :- encoding(utf8). %string_metta(Text) --> `#|`, !, zalmetta_wayzz_metta(string_until_metta(Text,`|#`)),!. @@ -480,7 +480,7 @@ %sexpr(L) --> sblank,!,sexpr(L),!. %sexpr(_) --> `)`,!,{trace,break,throw_reader_error(": an object cannot start with #\\)")}. -sexpr(X,H,T):- zalwayzz(sexpr0(X),H,M),zalwayzz(swhite,M,T), nop(if_debugging(sreader,(wdmsg(sexpr(X))))),!. +sexpr(X,H,T):- zalwayzz(sexpr0(X),H,M),zalwayzz(swhite,M,T), nop(if_debugging(sreader,(fbug(sexpr(X))))),!. %sexpr(X,H,T):- zalwayzz(sexpr0(X,H,T)),!,swhite. is_common_lisp:- fail. @@ -561,6 +561,7 @@ % c:/opt/logicmoo_workspace/packs_sys/logicmoo_opencog/guile/module/ice-9/and-let-star.scm priority_symbol((`|-`)). +/* priority_symbol((`#=`)). priority_symbol((`#+`)). priority_symbol((`#-`)). @@ -578,19 +579,18 @@ priority_symbol((`-1-`)). priority_symbol((`1+`)). priority_symbol((`1-`)). +*/ sym_or_num('$COMPLEX'(L)) --> `#C(`,!, swhite, sexpr_list(L), swhite. %sym_or_num((E)) --> unsigned_number(S),{number_string(E,S)}. %sym_or_num((E)) --> unsigned_number(S),{number_string(E,S)}. -sym_or_num((E)) --> lnumber(E),swhite,!. +%sym_or_num((E)) --> lnumber(E),swhite,!. sym_or_num(E) --> rsymbol_maybe(``,E),!. %sym_or_num('#'(E)) --> [C],{atom_codes(E,[C])}. sym_or_num(E) --> dcg_xor(rsymbol(``,E),lnumber(E)),!. - - -sym_or_num(E) --> dcg_xor(rsymbol(``,E),lnumber(E)),!. +%sym_or_num(E) --> dcg_xor(rsymbol(``,E),lnumber(E)),!. % sym_or_num('#'(E)) --> [C],{atom_codes(E,[C])}. @@ -676,8 +676,8 @@ %s_string_cont(Until,"") --> Until,!, swhite. :- encoding(iso_latin_1). sexpr_string(Text) --> `"`, !, zalwayzz(read_string_until(Text,`"`)),!. -sexpr_string(Text) --> `�`, !, zalwayzz(read_string_until(Text,(`�`;`�`))),!. -sexpr_string(Text) --> (`�`;`�`), !, zalwayzz(read_string_until(Text,(`�`;`�`))),!. +sexpr_string(Text) --> `“`, !, zalwayzz(read_string_until(Text,(`”`;`“`))),!. +sexpr_string(Text) --> (`”`;`“`), !, zalwayzz(read_string_until(Text,(`”`;`“`))),!. sexpr_string(Text) --> `#|`, !, zalwayzz(read_string_until(Text,`|#`)),!. :- encoding(utf8). %sexpr_string([C|S],End) --> `\\`,!, zalwayzz(escaped_char(C)),!, sexpr_string(S,End). @@ -900,8 +900,8 @@ char_code_int(Char,Code):- notrace_catch_fail(char_code(Char,Code)),!. char_code_int(Char,Code):- notrace_catch_fail(atom_codes(Char,[Code])),!. char_code_int(Char,Code):- atom(Char),name_to_charcode(Char,Code),!. -char_code_int(Char,Code):- var(Char),!,wdmsg(char_code_int(Char,Code)), only_debug(break). -char_code_int(Char,Code):- wdmsg(char_code_int(Char,Code)),only_debug(break). +char_code_int(Char,Code):- var(Char),!,fbug(char_code_int(Char,Code)), only_debug(break). +char_code_int(Char,Code):- fbug(char_code_int(Char,Code)),only_debug(break). char_code_to_char(N,S):- atom(N),atom_codes(N,[_]),!,S=N. char_code_to_char(N,S):- atom(N),!,S=N. @@ -1614,3 +1614,4 @@ %:- fixup_exports. %:- endif. + diff --git a/metta_vspace/pyswip/metta_server.pl b/metta_vspace/pyswip/metta_server.pl index 5082edea..58c0df71 100755 --- a/metta_vspace/pyswip/metta_server.pl +++ b/metta_vspace/pyswip/metta_server.pl @@ -30,11 +30,14 @@ tcp_bind(Socket, Port), tcp_listen(Socket, 5), tcp_open_socket(Socket, ListenFd), fbug(run_vspace_server(Port)), + retractall(vspace_port(_)), + assert(vspace_port(Port)), accept_vspace_connections(ListenFd). accept_vspace_connections(ListenFd) :- tcp_accept(ListenFd, ClientFd, ClientAddr), - format(atom(ThreadAlias), 'client_~w', [ClientAddr]), + format(atom(ThreadAlias0), 'client_~w_~w_', [ClientAddr,ClientFd]), + gensym(ThreadAlias0,ThreadAlias), thread_create(setup_call_cleanup( tcp_open_socket(ClientFd, Stream), ignore(handle_vspace_client(Stream)), @@ -49,9 +52,17 @@ ;send_term(Stream, 'failed'))), handle_vspace_client(Stream). +any_to_i(A,I):- integer(A),I=A. +any_to_i(A,I):- format(atom(Ay),'~w',[A]),atom_number(Ay,I). % Start the server automatically on a default port or a specified port :- dynamic vspace_port/1. -start_vspace_server:- ( vspace_port(Port) -> start_vspace_server(Port); start_vspace_server(3023) ). +get_vspace_port(Port):- current_prolog_flag('argv',L),member(AA,L),atom_concat('--server=',P,AA),atom_number(P,Port),!,set_prolog_flag('port',Port). +get_vspace_port(Port):- current_prolog_flag('port',P),any_to_i(P,Port),!. +get_vspace_port(Port):- vspace_port(Port),!. +get_vspace_port(Port):- Port = 3023. +start_vspace_server:- is_compiling,!. +start_vspace_server:- thread_property(VSS,TS),VSS=vspace_server,TS=status(running),!. +start_vspace_server:- get_vspace_port(Port), start_vspace_server(Port),!. % Connects to the server and sends the goal remote_call(ServerPort, Goal) :- @@ -68,13 +79,14 @@ tcp_open_socket(Socket, Stream). % Helper to send goal and receive response -send_term(Stream, Goal) :- write_canonical(Stream, Goal),writeln(Stream, '.'), flush_output(Stream). +send_term(Stream, MeTTa) :- write_canonical(Stream, MeTTa),writeln(Stream, '.'), flush_output(Stream). +recv_term(Stream, MeTTa) :- read_term(Stream, MeTTa, []). % Read and process the server's response read_response(Stream,Goal) :- flush_output(Stream), - repeat, read_term(Stream,Response,[]), + repeat, recv_term(Stream,Response), (Response == failed -> (!,fail) ; (Response = error(Throw) -> throw(Throw) ; ((Response = success(Goal,WasDet)), @@ -85,9 +97,29 @@ :- dynamic remote_code/3. % Maps predicate to server +our_address(Host:Port):- gethostname(Host),vspace_port(Port). +we_exist(Addr):- our_address(Addr). + +they_exist(Addr):- execute_goal(we_exist(Addr)), \+ our_address(Addr). +% tell the server that took our place about us... +register_ready:- + our_address(Ours), + forall(was_vspace_server_in_use(Port), + remote_call(Port,register_remote_code(we_exist(_),true,Ours))). +register_gone:- + our_address(Ours), + forall(they_exist(Addr), + remote_call(Addr,register_remote_code(we_exist(_),Ours))). + % Registers a predicate to a server -register_remote_code(Predicate, NonDet, Server) :- assertz(remote_code(Predicate, NonDet, Server)). +register_remote_code(Predicate, NonDet, Server) :- + unregister_remote_code(Predicate, Server), + assertz(remote_code(Predicate, NonDet, Server)). +unregister_remote_code(Predicate, Server) :- retractall(remote_code(Predicate, _, Server)). + + +execute_goal(Goal):- execute_goal(Goal, _). % Meta-interpreter with cut handling execute_goal(Goal, IsCut) :- remote_code(Goal, NonDet, Server), % If the goal is registered for a server, call remotely @@ -204,6 +236,5 @@ retractall(result(Tag, _, _, _)). - :- initialization(start_vspace_server). diff --git a/metta_vspace/pyswip/metta_utils.pl b/metta_vspace/pyswip/metta_utils.pl index fae8da81..523b3792 100755 --- a/metta_vspace/pyswip/metta_utils.pl +++ b/metta_vspace/pyswip/metta_utils.pl @@ -14,6 +14,9 @@ :- ensure_loaded(library(dictoo)). :- endif. +cleanup_debug:- + forall((clause(prolog_debug:debugging(A1,B,C),Body,Cl1), clause(prolog_debug:debugging(A2,B,C),Body,Cl2),A1=@=A2,Cl1\==Cl2), + erase(Cl2)). :- export(plain_var/1). plain_var(V):- notrace((var(V), \+ attvar(V), \+ get_attr(V,ci,_))). diff --git a/metta_vspace/pyswip/swi_support.pl b/metta_vspace/pyswip/swi_support.pl index 1854606e..812ce732 100755 --- a/metta_vspace/pyswip/swi_support.pl +++ b/metta_vspace/pyswip/swi_support.pl @@ -62,8 +62,8 @@ set_option_value0(N,V):- p2mE(V,VV),!, catch(nb_setval(N,VV),E,fbug(E)), - catch(create_prolog_flag(N,V,[keep(false),access(read_write), type(term)]),E,fbug(E)), - catch(set_prolog_flag(N,V),E,fbug(E)),!. + catch(create_prolog_flag(N,V,[keep(false),access(read_write), type(term)]),E2,fbug(E2)), + catch(set_prolog_flag(N,V),E3,fbug(E3)),!. kaggle_arc:- \+ exists_directory('/opt/logicmoo_workspace/packs_sys/logicmoo_agi/prolog/kaggle_arc/'), !. %kaggle_arc:- !.