From cd60816429a14d984ab24ea46e5abcba5f13fcbe Mon Sep 17 00:00:00 2001 From: Simon Forman Date: Sun, 11 Aug 2019 17:48:29 -0700 Subject: [PATCH] Build math & comparision functions. --- thun/gnu-prolog/Makefile | 5 +++ thun/gnu-prolog/math.pl | 44 +++++++++++++++++++++++ thun/gnu-prolog/meta-math.pl | 70 ++++++++++++++++++++++++++++++++++++ 3 files changed, 119 insertions(+) create mode 100644 thun/gnu-prolog/math.pl create mode 100644 thun/gnu-prolog/meta-math.pl diff --git a/thun/gnu-prolog/Makefile b/thun/gnu-prolog/Makefile index a3dd65f..2c80052 100644 --- a/thun/gnu-prolog/Makefile +++ b/thun/gnu-prolog/Makefile @@ -10,3 +10,8 @@ defs.pl: meta-defs.pl parser.pl defs.txt thun.pl --consult-file thun.pl \ --query-goal do +math.pl: meta-math.pl + gprolog \ + --consult-file meta-math.pl \ + --query-goal do + diff --git a/thun/gnu-prolog/math.pl b/thun/gnu-prolog/math.pl new file mode 100644 index 0000000..da60453 --- /dev/null +++ b/thun/gnu-prolog/math.pl @@ -0,0 +1,44 @@ +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 --git a/thun/gnu-prolog/meta-math.pl b/thun/gnu-prolog/meta-math.pl new file mode 100644 index 0000000..0d76518 --- /dev/null +++ b/thun/gnu-prolog/meta-math.pl @@ -0,0 +1,70 @@ +/* + +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), + print_o(Stream, math_operator(Op)), + print_o(Stream, comparison_operator(Op)), + print_o(Stream, comparison_operator(Op, Po)), + close(Stream), + halt. + +