changeset db86bcbb30cb in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=db86bcbb30cb user: Simon Forman <sform****@hushm*****> date: Sun Aug 11 17:48:29 2019 -0700 description: Build math & comparision functions. changeset 7629cb8c1ad4 in joypy/Joypy details: http://hg.osdn.jp/view/joypy/Joypy?cmd=changeset;node=7629cb8c1ad4 user: Simon Forman <sform****@hushm*****> date: Sun Aug 11 18:45:57 2019 -0700 description: Multifile func/3. diffstat: thun/gnu-prolog/Makefile | 12 +++++- thun/gnu-prolog/main.pl | 4 +- thun/gnu-prolog/math.pl | 45 +++++++++++++++++++++++++++ thun/gnu-prolog/meta-math.pl | 71 ++++++++++++++++++++++++++++++++++++++++++++ thun/gnu-prolog/thun.pl | 1 + 5 files changed, 129 insertions(+), 4 deletions(-) diffs (173 lines): diff -r 27d6936bbc54 -r 7629cb8c1ad4 thun/gnu-prolog/Makefile --- a/thun/gnu-prolog/Makefile Sun Aug 11 17:00:38 2019 -0700 +++ b/thun/gnu-prolog/Makefile Sun Aug 11 18:45:57 2019 -0700 @@ -1,7 +1,8 @@ -GPLC_OPTIONS="--min-size" +#GPLC_OPTIONS=--min-size +GPLC_OPTIONS=--no-top-level -thun: thun.pl parser.pl defs.pl main.pl - gplc $(GPLC_OPTIONS) -o thun thun.pl parser.pl defs.pl main.pl +thun: thun.pl parser.pl defs.pl main.pl math.pl Makefile + gplc $(GPLC_OPTIONS) -o thun thun.pl parser.pl defs.pl main.pl math.pl defs.pl: meta-defs.pl parser.pl defs.txt thun.pl gprolog \ @@ -10,3 +11,8 @@ --consult-file thun.pl \ --query-goal do +math.pl: meta-math.pl + gprolog \ + --consult-file meta-math.pl \ + --query-goal do + diff -r 27d6936bbc54 -r 7629cb8c1ad4 thun/gnu-prolog/main.pl --- a/thun/gnu-prolog/main.pl Sun Aug 11 17:00:38 2019 -0700 +++ b/thun/gnu-prolog/main.pl Sun Aug 11 18:45:57 2019 -0700 @@ -33,7 +33,9 @@ loop(NextLine, S, Out). -do_line(Line, In, Out) :- phrase(joy_parse(E), Line), thun(E, In, Out). +do_line(Line, In, Out) :- + phrase(joy_parse(E), Line), + thun(E, In, Out). do_line(_Line, S, S) :- write('Err'), nl. prompt :- write(`joy? `). diff -r 27d6936bbc54 -r 7629cb8c1ad4 thun/gnu-prolog/math.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thun/gnu-prolog/math.pl Sun Aug 11 18:45:57 2019 -0700 @@ -0,0 +1,45 @@ +:- multifile(func/3). +func(+, [A, B|C], [D|C]) :- + E =.. [+, B, A], + catch(D is E, _, D = E). + +func(-, [A, B|C], [D|C]) :- + E =.. [-, B, A], + catch(D is E, _, D = E). + +func(*, [A, B|C], [D|C]) :- + E =.. [*, B, A], + catch(D is E, _, D = E). + +func(/, [A, B|C], [D|C]) :- + E =.. [/, B, A], + catch(D is E, _, D = E). + +func(mod, [A, B|C], [D|C]) :- + E =.. [mod, B, A], + catch(D is E, _, D = E). + +func(>, [A, B|C], [D|C]) :- + E =.. [>, B, A], + catch((E -> D = true ; D = false), _, D = E). + +func(<, [A, B|C], [D|C]) :- + E =.. [<, B, A], + catch((E -> D = true ; D = false), _, D = E). + +func(>=, [A, B|C], [D|C]) :- + E =.. [>=, B, A], + catch((E -> D = true ; D = false), _, D = E). + +func(<=, [A, B|C], [D|C]) :- + E =.. [=<, B, A], + catch((E -> D = true ; D = false), _, D = E). + +func(=, [A, B|C], [D|C]) :- + E =.. [=:=, B, A], + catch((E -> D = true ; D = false), _, D = E). + +func(<>, [A, B|C], [D|C]) :- + E =.. [=\=, B, A], + catch((E -> D = true ; D = false), _, D = E). + diff -r 27d6936bbc54 -r 7629cb8c1ad4 thun/gnu-prolog/meta-math.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/thun/gnu-prolog/meta-math.pl Sun Aug 11 18:45:57 2019 -0700 @@ -0,0 +1,71 @@ +/* + +To handle comparision operators the possibility of exceptions due to +insufficiently instantiated arguments must be handled. First try to make +the comparison and set the result to a Boolean atom. If an exception +happens just leave the comparison expression as the result and some other +function or combinator will deal with it. Example: + + func(>, [A, B|S], [C|S]) :- catch( + (B > A -> C=true ; C=false), + _, + C=(B>A) % in case of error. + ). + +To save on conceptual overhead I've defined a term_expansion/2 that sets +up the func/3 for each op. +*/ + +term_expansion(comparison_operator(X), (func(X, [A, B|S], [C|S]) :- + F =.. [X, B, A], catch((F -> C=true ; C=false), _, C=F))). + +% I don't use Prolog-compatible op symbols in all cases. +term_expansion(comparison_operator(X, Y), (func(X, [A, B|S], [C|S]) :- + F =.. [Y, B, A], catch((F -> C=true ; C=false), _, C=F))). + +% Likewise for math operators, try to evaluate, otherwise use the +% symbolic form. + +term_expansion(math_operator(X), (func(X, [A, B|S], [C|S]) :- + F =.. [X, B, A], catch(C is F, _, C=F))). + +term_expansion(math_operator(X, Y), (func(X, [A, B|S], [C|S]) :- + F =.. [Y, B, A], catch(C is F, _, C=F))). + + +% Symbolic math. Compute the answer, or derivative, or whatever, later. +math_operator(+). +math_operator(-). +math_operator(*). +math_operator(/). +math_operator(mod). + + +comparison_operator(>). +comparison_operator(<). +comparison_operator(>=). +comparison_operator(<=, =<). +comparison_operator(=, =:=). +comparison_operator(<>, =\=). + + +expand_op(Op, Term) :- Op, expand_term(Op, Term). + +print_o(Stream, Op) :- + findall(Term, expand_op(Op, Term), List), + maplist(writeln(Stream), List). + +writeln(Stream, Thing) :- + portray_clause(Stream, Thing), + nl(Stream). + +do :- + open(`math.pl`, write, Stream), + write(Stream, `:- multifile(func/3).`), nl(Stream), + print_o(Stream, math_operator(Op)), + print_o(Stream, comparison_operator(Op)), + print_o(Stream, comparison_operator(Op, Po)), + close(Stream), + halt. + + diff -r 27d6936bbc54 -r 7629cb8c1ad4 thun/gnu-prolog/thun.pl --- a/thun/gnu-prolog/thun.pl Sun Aug 11 17:00:38 2019 -0700 +++ b/thun/gnu-prolog/thun.pl Sun Aug 11 18:45:57 2019 -0700 @@ -19,6 +19,7 @@ */ % :- dynamic(func/3). % :- discontiguous(func/3). +:- multifile(func/3). /* Interpreter