# HG changeset patch # User HackEso # Date 1563313047 0 # Node ID 318de151d0ec5ddf54462259af20f220d8ae6d67 # Parent d054de7f80f216cb39018a72ebf4749e8a7bd8a3 python3 -cimport os,zipfile; os.chdir("ibin/brachylog"); zipfile.ZipFile("master.zip").extractall() diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/.gitignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/.gitignore Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,16 @@ +*.class + +# Mobile Tools for Java (J2ME) +.mtj.tmp/ + +# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml +hs_err_pid* + +compiled_brachylog.pl +*.brachylog +*.aux +*.bbl +*.blg +*.log +*.gz +src/compiled_brachylog_eval.pl diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/LICENSE --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/LICENSE Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 - 2019 Julien Cumin + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/README.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/README.md Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,56 @@ +

Brachylog

+ +# What is it? + +Brachylog is a declarative logic programming language much like Prolog. Brachylog is designed to be much terser than Prolog, while retaining some readability. + +Currently in development. + +Brachylog uses [SWI-Prolog](http://www.swi-prolog.org/) as Prolog engine. + +## How do I use this? + +### Documentation + +Check out [Brachylog's Wiki](https://github.com/JCumin/Brachylog/wiki) if you want to learn how to write programs in this language. + +You may want to watch this [**short video introduction to Brachylog**](https://www.youtube.com/watch?v=XYVhZ-MFcUs). + +### Try it online! + +You can try out Brachylog on [Try it online!](https://tio.run/nexus/brachylog2), thanks to @DennisMitchell. + +### Brachylog language bar + +[You can find here](https://abrudz.github.io/lb/brachylog) the Brachylog language bar which gives you access to all symbols used in Brachylog on any webpage (by clicking on the symbols or by inputing shortcuts), thanks to @abrudz. + +### The interpreter + +Brachylog's interpreter is entirely written in Prolog. Therefore, installing [SWI-Prolog](http://www.swi-prolog.org/) (version 7 and up) is mandatory to use Brachylog (We do not guarantee that Brachylog's interpreter will be compatible with any other Prolog implementation). + +To run Brachylog's interpreter, start SWI-Prolog's interpreter inside the `src` directory available in this repository, and consult the file `brachylog.pl` (`consult(brachylog).`). Alternatively, you can run the interpreter with: + + $ swipl src/brachylog.pl + +You can then run Brachylog programs using different predicates: + + - `run_from_file(FileName, Input, Output)`: `FileName` is an atom (i.e. between single quotes `'`) representing the file containing your Brachylog code. For example: `run_from_file('code.brachylog',"Test Input",Z)`. + + - `run_from_atom(Code, Input, Output)`: `Code` is an atom (i.e. between single quotes `'`) containing your Brachylog code. For example: `run_from_atom('∧"Hello, World!"w',_,_)`. Note that you will have to escape certain characters in `Code`. + + - `run(Input, Output)`: This will run a Brachylog program that has already been transpiled to Prolog using either of the two previous predicates. More precisely, this will query `brachylog_main/2` in the file `compiled_brachylog.pl`. + +The first two predicates will transpile your Brachylog program into Prolog, subsequently generating a file called `compiled_brachylog.pl` in the same directory that contains `brachylog.pl`. The three run predicates will then consult it and query `brachylog_main/3`. + +Note that the first two run predicates also exist with either no `Output` argument, or with no `Input` nor `Output` argument, if necessary. For example, `run_from_file('code.brachylog')` is equivalent to `run_from_file('code.brachylog', _, _)`. + + +### Contributors + +- Julien Cumin - [@JCumin](https://github.com/JCumin) + +- Markus Triska - [@triska](https://github.com/triska) + +- ais523 + +- [@UnrelatedString](https://github.com/UnrelatedString) diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/misc/brachylog_logo.png Binary file ibin/brachylog/Brachylog-master/misc/brachylog_logo.png has changed diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/misc/brachylog_logo.svg --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/misc/brachylog_logo.svg Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,162 @@ + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/misc/brachylog_mini_logo.png Binary file ibin/brachylog/Brachylog-master/misc/brachylog_mini_logo.png has changed diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/brachylog.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/brachylog.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,218 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- use_module(transpile). +:- use_module(symbols). +:- use_module(utils). +:- use_module(predicates). +:- use_module(metapredicates). +:- use_module(constraint_variables). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + RUN_FROM_FILE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +run_from_file(FilePath) :- + run_from_file(FilePath, 'ignore', 'ignore'). +run_from_file(FilePath, Input) :- + run_from_file(FilePath, Input, 'ignore'). +run_from_file(FilePath, Input, Output) :- + read_file(FilePath, Code), + !, + run_from_atom(Code, Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + RUN_FROM_ATOM +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +run_from_atom(Code) :- + run_from_atom(Code, 'ignore', 'ignore'). +run_from_atom(Code, Input) :- + run_from_atom(Code, Input, 'ignore'). +run_from_atom(Code, Input, Output) :- + parse(Code, 'compiled_brachylog.pl'), + !, + run(Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + RUN +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +run(Input, Output) :- + set_prolog_flag(answer_write_options, [quoted(true), + portray(true), + max_depth(10), + spacing(next_argument), + max_depth(0)]), + set_prolog_flag(print_write_options, [portray(true), + quoted(true), + numbervars(true), + max_depth(0)]), + consult('compiled_brachylog.pl'), + ( \+ var(Input), + Input \= 'ignore', + parse_argument(Input, ParsedInput) + ; true + ), + ( \+ var(Output), + Output \= 'ignore', + parse_argument(Output, ParsedOutput) + ; true + ), + !, + call(brachylog_main, _, _, ParsedInput, ParsedOutput), + ( var(Input) -> + brachylog_prolog_variable(ParsedInput, Input) + ; true + ), + ( var(Output) -> + brachylog_prolog_variable(ParsedOutput, Output) + ; true + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + RUN_FROM_FILES_NO_FILE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +run_from_files_no_file(FilePath, InputPath, OutputPath) :- + read_file(FilePath, Atom), + !, + ( read_file(InputPath, Input), + Input \= '' + ; Input = 'ignore' + ), + !, + ( read_file(OutputPath, Output), + Output \= '' + ; Output = 'ignore' + ), + !, + parse_no_file(Atom, Predicates), + !, + ( contains_write(Atom) -> + ContainsWrite = 'yes' + ; ContainsWrite = 'no' + ), + !, + set_prolog_flag(answer_write_options, [quoted(true), + portray(true), + max_depth(10), + spacing(next_argument), + max_depth(0)]), + set_prolog_flag(print_write_options, [portray(true), + quoted(true), + numbervars(true), + max_depth(0)]), + maplist(atomic_list_concat, Predicates, ConcatenatedPredicates), + maplist(read_term_from_atom_, ConcatenatedPredicates, AssertablePredicates), + maplist(assertz, AssertablePredicates), + ( Input \= 'ignore', + parse_argument(Input, ParsedInput), + \+ var(ParsedInput), + ReportInput = 'no' + ; Input == 'ignore', + ReportInput = 'no' + ; ReportInput = 'yes', + true + ), + ( Output \= 'ignore', + parse_argument(Output, ParsedOutput), + \+ var(ParsedOutput), + ReportOutput = 'no' + ; Output == 'ignore', + ReportOutput = 'no' + ; ReportOutput = 'yes', + true + ), + !, + ( call(brachylog_main, _, _, ParsedInput, ParsedOutput) -> + ( ReportInput = 'yes' -> + brachylog_prolog_variable(ParsedInput, InputProlog) + ; true + ), + ( ReportOutput = 'yes' -> + brachylog_prolog_variable(ParsedOutput, OutputProlog) + ; true + ), + ( ReportInput = 'yes', + Bindings = [Input=InputProlog] + ; Bindings = [] + ), + ( ReportOutput = 'yes', + BindingsFinal = [Output=OutputProlog|Bindings] + ; BindingsFinal = Bindings, + true + ), + ( (ReportInput = 'yes' ; ReportOutput = 'yes'), + write('\n') + ; true + ), + reverse(BindingsFinal, RBindings), + report_bindings(RBindings), + ( ReportInput = 'no', + ReportOutput = 'no', + ContainsWrite = 'no', + write('true.') + ; true + ) + ; ( ContainsWrite = 'no', + write('false.') + ; true + ) + ). + +read_term_from_atom_(A, B) :- + read_term_from_atom(A, B, []). + +% Credits to M. Triska +% See: http://stackoverflow.com/a/38284692/2554145 +report_bindings(NameVars) :- + phrase(bindings(NameVars), Bs), + format("~s", [Bs]). + +bindings([]) --> []. +bindings([E]) --> name_var(E). +bindings([E1,E2|Rest]) --> name_var(E1), ",\n", bindings([E2|Rest]). + +name_var(Name=Var) --> + format_("~w = ~q", [Name,Var]). + +format_(Format, Ls) --> + call(format_codes(Format, Ls)). + +format_codes(Format, Ls, Cs0, Cs) :- + format(codes(Cs0, Cs), Format, Ls). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + READ_FILE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +read_file(FilePath, Code) :- + ( exists_file(FilePath), + open(FilePath, read, File), + read_file_(File, Chars), + close(File), + atomic_list_concat(Chars, Code) + ; throw('The file does not exist.') + ), + !. + +read_file_(File, []) :- + at_end_of_stream(File). +read_file_(File, [H|T]) :- + \+ at_end_of_stream(File), + get_char(File, H), + read_file_(File, T). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/constraint_variables.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/constraint_variables.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,147 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(constraint_variables, [constraintA/1, + constraintB/1, + constraintC/1, + constraintD/1, + constraintE/1, + constraintF/1, + constraintG/1, + constraintH/1, + constraintI/1, + constraintJ/1, % Unused + constraintK/1, % Unused + constraintL/1, % Unused + constraintM/1, + constraintN/1, + constraintO/1, + constraintP/1, + constraintQ/1, % Unused + constraintR/1, + constraintS/1, + constraintT/1, + constraintU/1, % Unused + constraintV/1, % Unused + constraintW/1, + constraintX/1, + constraintY/1, + constraintZ/1 + ]). + +:- use_module(library(clpfd)). +:- use_module(utils). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + CONSTRAINT[A-Z]/1 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +constraintA(_) :- + true. + + +constraintB(_) :- + true. + + +constraintC([_,_]). + + +constraintD('integer':X) :- + X in 0..9. + + +constraintE([]). + + +constraintF(_) :- + true. + + +constraintG(_) :- + true. + + +constraintH(_) :- + true. + + +constraintI('integer':X) :- + X in inf..sup. + + +constraintJ(_) :- % Unused + true. + + +constraintK(_) :- % Unused + true. + + +constraintL(_) :- % Unused + true. + + +constraintM([_,_|_]). + + +constraintN(_) :- + true. + + +constraintO([_]). + + +constraintP(_) :- + true. + + +constraintQ(_) :- % Unused + true. + + +constraintR(_) :- + true. + + +constraintS('string':_). + + +constraintT([_,_,_]). + + +constraintU(_) :- % Unused + true. + + +constraintV(_) :- % Unused + true. + + +constraintW(_) :- + true. + + +constraintX(_) :- + true. + + +constraintY(_) :- + true. + + +constraintZ(_) :- + true. diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/metapredicates.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/metapredicates.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,690 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(metapredicates, [brachylog_meta_accumulate/6, + brachylog_meta_bagof/6, + brachylog_meta_count/6, + brachylog_meta_declare/6, + brachylog_meta_existence/6, + brachylog_meta_find/6, + brachylog_meta_groupby/6, + brachylog_meta_head/6, + brachylog_meta_iterate/6, + brachylog_meta_leftfold/6, + brachylog_meta_map/6, + brachylog_meta_nonexistence/6, + brachylog_meta_orderby/6, + brachylog_meta_select/6, + brachylog_meta_tail/6, + brachylog_meta_unique/6, + brachylog_meta_verify/6, + brachylog_meta_zip/6 + ]). + +:- use_module(library(clpfd)). +:- use_module(predicates). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_ACCUMULATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_accumulate(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_accumulate(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_accumulate(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_accumulate(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_accumulate(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_accumulate(GlobalVariables, 'integer':1, P, Sub, Input, Output). +brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, 'string':Input, Output) :- + brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, ['string':Input], Output). +brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, 'integer':Input, Output) :- + brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, ['integer':Input], Output). +brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, 'float':Input, Output) :- + brachylog_meta_accumulate(GlobalVariables, Sup, P, Sub, ['float':Input], Output). +brachylog_meta_accumulate(_, 'integer':0, _P, _Sub, Input, Input). +brachylog_meta_accumulate(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 0, + is_brachylog_list(Input), + ( GlobalVariables = 'ignore', + call(P, Sub, Input, E) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, E) + ), + J #= I - 1, + append(Input, [E], F), + brachylog_meta_accumulate(GlobalVariables, 'integer':J, P, Sub, F, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_BAGOF +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_bagof(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_bagof(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_bagof(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_bagof(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_bagof(_, 'integer':0, _, _, _, []). +brachylog_meta_bagof(GlobalVariables, 'default', P, Sub, Input, Output) :- + bagof(X, + ( GlobalVariables = 'ignore', + call(P, Sub, Input, X) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, X) + ), + Output). +brachylog_meta_bagof(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 0, + bagof(X, call_firstn( + ( GlobalVariables = 'ignore', + call(P, Sub, Input, X) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, X) + ), I), + Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_COUNT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_count(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_count(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_count(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_count(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_count(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_count(GlobalVariables, 'integer':0, P, Sub, Input, Output). +brachylog_meta_count(GlobalVariables, 'integer':0, P, Sub, Input, Output) :- + brachylog_meta_find(GlobalVariables, 'default', P, Sub, Input, E), + brachylog_length('default', E, Output). +brachylog_meta_count(GlobalVariables, 'integer':1, P, Sub, Input, Output) :- + brachylog_meta_unique(GlobalVariables, 'default', P, Sub, Input, E), + brachylog_length('default', E, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_DECLARE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_declare(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_declare(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_declare(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_declare(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_declare(GlobalVariables, 'default', P, Sub, [H,T], T) :- + ( GlobalVariables = 'ignore', + call(P, Sub, H, T) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, H, T) + ). +brachylog_meta_declare(GlobalVariables, 'integer':0, P, Sub, [H,T], [H,T]) :- + ( GlobalVariables = 'ignore', + call(P, Sub, H, T) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, H, T) + ). +brachylog_meta_declare(GlobalVariables, 'integer':1, P, Sub, [H,T], H) :- + ( GlobalVariables = 'ignore', + call(P, Sub, T, H) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, T, H) + ). +brachylog_meta_declare(GlobalVariables, 'integer':2, P, Sub, [H,T], [H,T]) :- + ( GlobalVariables = 'ignore', + call(P, Sub, T, H) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, T, H) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_EXISTENCE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_existence(GlobalVariables, 'first', P, Sub, [I|Input], Arg) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_existence(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_existence(GlobalVariables, 'last', P, Sub, Input, Arg) :- + reverse(Input, [I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_existence(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_existence(GlobalVariables, 'integer':I, P, Sub, Input, Input) :- + dif(I, 'default'), + brachylog_meta_existence(GlobalVariables, P, Sub, Input, 'integer':I). +brachylog_meta_existence(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_existence(GlobalVariables, P, Sub, Input, Output). + +brachylog_meta_existence(GlobalVariables, P, Sub, Input, Output) :- + brachylog_in('default', Input, E), + ( GlobalVariables = 'ignore', + call(P, Sub, E, Output) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, E, Output) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_FIND + + Credits to @false for call_firstf/2 and call_nth/2 + http://stackoverflow.com/a/20866206/2554145 + http://stackoverflow.com/a/11400256/2554145 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_find(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_find(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_find(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_find(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_find(_, 'integer':0, _, _, _, []). +brachylog_meta_find(GlobalVariables, 'default', P, Sub, Input, Output) :- + findall(X, + ( GlobalVariables = 'ignore', + call(P, Sub, Input, X) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, X) + ), + Output). +brachylog_meta_find(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 0, + findall(X, call_firstn( + ( GlobalVariables = 'ignore', + call(P, Sub, Input, X) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, X) + ), I), + Output). + +call_firstn(Goal_0, N) :- + N + N mod 1 >= 0, % ensures that N >=0 and N is an integer + call_nth(Goal_0, Nth), + ( Nth == N -> ! ; true ). + +call_nth(Goal_0, C) :- + State = count(0, _), + Goal_0, + arg(1, State, C1), + C2 is C1+1, + nb_setarg(1, State, C2), + C = C2. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_GROUPBY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_groupby(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_groupby(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_groupby(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_groupby(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_groupby(GlobalVariables, 'default', P, Sub, Input, Output) :- + ( is_brachylog_list(Input) -> FixedInput = Input + ; brachylog_elements('default', Input, FixedInput) + ), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, FixedInput, L), + brachylog_zip('default', [L,Input], L2), + brachylog_meta_groupby_group(L2, L3), + maplist(brachylog_meta_groupby_tail, L3, Output). + +brachylog_meta_groupby_group(L, Gs) :- + brachylog_meta_groupby_group(L, [], Gs). + +brachylog_meta_groupby_group([], Gs, Gs). +brachylog_meta_groupby_group([[G,H]|T], TempGs, Gs) :- + ( member(G:L, TempGs) -> + reverse(L, RL), + reverse([H|RL], L2), + select(G:L, TempGs, G:L2, TempGs2) + ; append(TempGs, [G:[H]], TempGs2) + ), + brachylog_meta_groupby_group(T, TempGs2, Gs). + +brachylog_meta_groupby_tail(_:T, T). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_HEAD +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_head(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_head(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_head(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_head(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_head(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_head(GlobalVariables, 'integer':1, P, Sub, Input, Output). +brachylog_meta_head(_, 'integer':0, _, _, Input, Input). +brachylog_meta_head(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 0, + brachylog_head('integer':I, Input, Heads), + brachylog_behead('integer':I, Input, Tails), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Heads, NewHeads), + brachylog_concatenate('default', [NewHeads,Tails], Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_ITERATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_iterate(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_iterate(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_iterate(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_iterate(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_iterate(_, 'integer':0, _, _, Input, Input). +brachylog_meta_iterate(GlobalVariables, 'default', P, Sub, Input, Output) :- + I #>= 1, + brachylog_meta_iterate(GlobalVariables, 'integer':I, P, Sub, Input, Output). +brachylog_meta_iterate(GlobalVariables, 'integer':1, P, Sub, Input, Output) :- + ( GlobalVariables = 'ignore', + call(P, Sub, Input, Output) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, Output) + ). +brachylog_meta_iterate(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 1, + ( GlobalVariables = 'ignore', + call(P, Sub, Input, TOutput) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, TOutput) + ), + J #= I - 1, + brachylog_meta_iterate(GlobalVariables, 'integer':J, P, Sub, TOutput, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_LEFTFOLD +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_leftfold(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_leftfold(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_leftfold(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_leftfold(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_leftfold(GlobalVariables, 'default', P, Sub, 'string':S, Output) :- + brachylog_elements('default', 'string':S, E), + brachylog_meta_leftfold(GlobalVariables, 'default', P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'string':_ -> + Output = X + ; Output = O + ). +brachylog_meta_leftfold(GlobalVariables, 'default', P, Sub, 'integer':Input, Output) :- + brachylog_elements('default', 'integer':Input, E), + brachylog_meta_leftfold(GlobalVariables, 'default', P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'integer':_ -> + Output = X + ; Output = O + ). +brachylog_meta_leftfold(_, 'default', _P, _Sub, [], []). +brachylog_meta_leftfold(_, 'default', _P, _Sub, [X], [X]). +brachylog_meta_leftfold(GlobalVariables, 'default', P, Sub, [H,I|T], Output) :- + brachylog_meta_leftfold_(GlobalVariables, P, Sub, [I|T], H, Output). + +brachylog_meta_leftfold_(_, _P, _Sub, [], Output, Output). +brachylog_meta_leftfold_(GlobalVariables, P, Sub, [H|T], A, Output) :- + ( GlobalVariables = 'ignore', + call(P, Sub, [A,H], E) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, [A,H], E) + ), + brachylog_meta_leftfold_(GlobalVariables, P, Sub, T, E, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_MAP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_map(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_map(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_map(GlobalVariables, 'integer':0, P, Sub, Input, Output) :- + ( GlobalVariables = 'ignore', + call(P, Sub, Input, Output) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, Output) + ). +brachylog_meta_map(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_map(GlobalVariables, 'integer':1, P, Sub, Input, Output). +brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, 'string':S, Output) :- + brachylog_elements('default', 'string':S, E), + brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'string':_ -> + Output = X + ; Output = O + ). +brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, 'integer':Input, Output) :- + brachylog_elements('default', 'integer':Input, E), + brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'integer':_ -> + Output = X + ; Output = O + ). +brachylog_meta_map(GlobalVariables, 'integer':1, P, Sub, Input, Output) :- + ( GlobalVariables = 'ignore', + Pred =.. [P, Sub] + ; dif(GlobalVariables, 'ignore'), + Pred =.. [P, GlobalVariables, Sub] + ), + is_brachylog_list(Input), + maplist(Pred, Input, Output). +brachylog_meta_map(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 1, + J #= I - 1, + is_brachylog_list(Input), + maplist(brachylog_meta_map(GlobalVariables, 'integer':J, P, Sub), Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_NONEXISTENCE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_nonexistence(GlobalVariables, 'first', P, Sub, [I|Input], Arg) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_nonexistence(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_nonexistence(GlobalVariables, 'last', P, Sub, Input, Arg) :- + reverse(Input, [I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_nonexistence(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_nonexistence(GlobalVariables, 'integer':I, P, Sub, Input, Input) :- + dif(I, 'default'), + brachylog_meta_nonexistence(GlobalVariables, P, Sub, Input, 'integer':I). +brachylog_meta_nonexistence(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_nonexistence(GlobalVariables, P, Sub, Input, Output). + +brachylog_meta_nonexistence(GlobalVariables, P, Sub, Input, Output) :- + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Input, T), + brachylog_zip('default', [T,[Output]], Z), + brachylog_meta_map(GlobalVariables, 'default', brachylog_different, 'default', Z, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_ORDERBY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_orderby(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_orderby(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_orderby(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_orderby(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_orderby(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_orderby(GlobalVariables, 'integer':0, P, Sub, Input, Output). +brachylog_meta_orderby(GlobalVariables, 'integer':0, P, Sub, Input, Output) :- + ( is_brachylog_list(Input) -> FixedInput = Input + ; brachylog_elements('default', Input, FixedInput) + ), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, FixedInput, L), + brachylog_zip('default', [L,Input], L2), + brachylog_order(integer:0, L2, SL2), + ( SL2 = [] -> + Output = [] + ; brachylog_zip('default', SL2, [_,Output]) + ). +brachylog_meta_orderby(GlobalVariables, 'integer':1, P, Sub, Input, Output) :- + ( is_brachylog_list(Input) -> FixedInput = Input + ; brachylog_elements('default', Input, FixedInput) + ), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, FixedInput, L), + brachylog_zip('default', [L,Input], L2), + brachylog_order(integer:1, L2, SL2), + ( SL2 = [] -> + Output = [] + ; brachylog_zip('default', SL2, [_,Output]) + ). +brachylog_meta_orderby(GlobalVariables, 'integer':2, P, Sub, Input, Output) :- + ( is_brachylog_list(Input) -> FixedInput = Input + ; brachylog_elements('default', Input, FixedInput) + ), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, FixedInput, L), + brachylog_order(integer:0, L, Output). +brachylog_meta_orderby(GlobalVariables, 'integer':3, P, Sub, Input, Output) :- + ( is_brachylog_list(Input) -> FixedInput = Input + ; brachylog_elements('default', Input, FixedInput) + ), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, FixedInput, L), + brachylog_order(integer:1, L, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_SELECT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_select(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_select(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_select(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_select(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_select(GlobalVariables, 'default', P, Sub, 'string':S, Output) :- + brachylog_elements('default', 'string':S, E), + brachylog_meta_select(GlobalVariables, 'default', P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'string':_ -> + Output = X + ; Output = O + ). +brachylog_meta_select(GlobalVariables, 'default', P, Sub, 'integer':S, Output) :- + brachylog_elements('default', 'integer':S, E), + brachylog_meta_select(GlobalVariables, 'default', P, Sub, E, O), + ( brachylog_concatenate('default', O, X), + X = 'integer':_ -> + Output = X + ; Output = O + ). +brachylog_meta_select(_, 'default', _, _, [], []). +brachylog_meta_select(GlobalVariables, 'default', P, Sub, [H|T], Output) :- + ( ( GlobalVariables = 'ignore', + call(P, Sub, H, H2) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, H, H2) + ) + *-> Output = [H2|T2] + ; Output = T2 + ), + brachylog_meta_select(GlobalVariables, 'default', P, Sub, T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_TAIL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_tail(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_tail(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_tail(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_tail(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_tail(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_tail(GlobalVariables, 'integer':1, P, Sub, Input, Output). +brachylog_meta_tail(_, 'integer':0, _, _, Input, Input). +brachylog_meta_tail(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + I #> 0, + brachylog_tail('integer':I, Input, Tails), + brachylog_knife('integer':I, Input, Heads), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Tails, NewTails), + brachylog_concatenate('default', [Heads,NewTails], Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_UNIQUE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_unique(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_unique(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_unique(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_unique(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_unique(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_unique_(GlobalVariables, 1, -1, P, Sub, Input, [], Output). +brachylog_meta_unique(_, 'integer':0, _, _, _, []). +brachylog_meta_unique(GlobalVariables, 'integer':I, P, Sub, Input, Output) :- + brachylog_meta_unique_(GlobalVariables, 1, I, P, Sub, Input, [], Output). + +brachylog_meta_unique_(_, _, 0, _, _, _, ROutput, Output) :- + reverse(ROutput, Output). +brachylog_meta_unique_(GlobalVariables, Nth, J, P, Sub, Input, A, Output) :- + J #\= 0, + ( call_nth( ( GlobalVariables = 'ignore', + call(P, Sub, Input, X) + ; dif(GlobalVariables, 'ignore'), + call(P, GlobalVariables, Sub, Input, X) + ), Nth) -> + ( \+ member(X, A) -> + M #= Nth + 1, + K #= J - 1, + brachylog_meta_unique_(GlobalVariables, M, K, P, Sub, Input, [X|A], Output) + ; M #= Nth + 1, + brachylog_meta_unique_(GlobalVariables, M, J, P, Sub, Input, A, Output) + ) + ; reverse(A, Output) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_VERIFY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_verify(GlobalVariables, 'first', P, Sub, [I|Input], Arg) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_verify(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_verify(GlobalVariables, 'last', P, Sub, Input, Arg) :- + reverse(Input, [I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_verify(GlobalVariables, P, Sub, Arg, I). +brachylog_meta_verify(GlobalVariables, 'integer':I, P, Sub, Input, Input) :- + dif(I, 'default'), + brachylog_meta_verify(GlobalVariables, P, Sub, Input, 'integer':I). +brachylog_meta_verify(GlobalVariables, 'default', P, Sub, Input, Output) :- + brachylog_meta_verify(GlobalVariables, P, Sub, Input, Output). + +brachylog_meta_verify(GlobalVariables, P, Sub, Input, Output) :- + brachylog_length('default', Input, L), + brachylog_length('default', T, L), + brachylog_equal('default', T, _), + brachylog_head('default', T, Output), + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Input, T). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_META_ZIP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_meta_zip(GlobalVariables, 'first', P, Sub, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_meta_zip(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_zip(GlobalVariables, 'last', P, Sub, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_meta_zip(GlobalVariables, 'integer':I, P, Sub, Arg, Output). +brachylog_meta_zip(GlobalVariables, 'default', P, Sub, Arg, Output) :- + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Arg, O), + brachylog_zip('default', [Arg,O], Output). +brachylog_meta_zip(GlobalVariables, 'integer':0, P, Sub, Arg, Output) :- + brachylog_meta_find(GlobalVariables, 'default', P, Sub, Arg, O), + brachylog_zip('default', [Arg,O], Output). +brachylog_meta_zip(GlobalVariables, 'integer':1, P, Sub, Arg, Output) :- + brachylog_meta_map(GlobalVariables, 'default', P, Sub, Arg, O), + brachylog_zip('default', [O,Arg], Output). +brachylog_meta_zip(GlobalVariables, 'integer':2, P, Sub, Arg, Output) :- + brachylog_meta_find(GlobalVariables, 'default', P, Sub, Arg, O), + brachylog_zip('default', [O,Arg], Output). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/predicates.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/predicates.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,3126 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(predicates, [%Symbols % Reversed version + brachylog_lessequal/3, brachylog_lessequal_reversed/3, + brachylog_greaterequal/3, brachylog_greaterequal_reversed/3, + brachylog_contains/3, brachylog_contains_reversed/3, + brachylog_in/3, brachylog_in_reversed/3, + brachylog_superset/3, brachylog_superset_reversed/3, + brachylog_subset/3, brachylog_subset_reversed/3, + brachylog_reverse/3, brachylog_reverse_reversed/3, + brachylog_call_predicate/3, brachylog_call_predicate_reversed/3, + brachylog_circular_permute_counterclockwise/3, brachylog_circular_permute_counterclockwise_reversed/3, + brachylog_circular_permute_clockwise/3, brachylog_circular_permute_clockwise_reversed/3, + brachylog_root/3, brachylog_root_reversed/3, + brachylog_ceil/3, brachylog_ceil_reversed/3, + brachylog_floor/3, brachylog_floor_reversed/3, + brachylog_range_ascending/3, brachylog_range_ascending_reversed/3, + brachylog_range_descending/3, brachylog_range_descending_reversed/3, + brachylog_natural_integer/3, brachylog_natural_integer_reversed/3, + brachylog_integer/3, brachylog_integer_reversed/3, + brachylog_float/3, brachylog_float_reversed/3, + brachylog_different/3, brachylog_different_reversed/3, + brachylog_identity/3, brachylog_identity_reversed/3, + brachylog_integer_division/3, brachylog_integer_division_reversed/3, + brachylog_multiply/3, brachylog_multiply_reversed/3, + brachylog_modulo/3, brachylog_modulo_reversed/3, + brachylog_exp/3, brachylog_exp_reversed/3, + brachylog_plus/3, brachylog_plus_reversed/3, + brachylog_minus/3, brachylog_minus_reversed/3, + brachylog_divide/3, brachylog_divide_reversed/3, + brachylog_less/3, brachylog_less_reversed/3, + brachylog_equal/3, brachylog_equal_reversed/3, + brachylog_greater/3, brachylog_greater_reversed/3, + brachylog_transpose/3, brachylog_transpose_reversed/3, + brachylog_power/3, brachylog_power_reversed/3, + + %Lowercase letters % Reversed version + brachylog_adfix/3, brachylog_adfix_reversed/3, + brachylog_behead/3, brachylog_behead_reversed/3, + brachylog_concatenate/3, brachylog_concatenate_reversed/3, + brachylog_duplicates/3, brachylog_duplicates_reversed/3, + brachylog_factors/3, brachylog_factors_reversed/3, + brachylog_group/3, brachylog_group_reversed/3, + brachylog_head/3, brachylog_head_reversed/3, + brachylog_index/3, brachylog_index_reversed/3, + brachylog_juxtapose/3, brachylog_juxtapose_reversed/3, + brachylog_knife/3, brachylog_knife_reversed/3, + brachylog_length/3, brachylog_length_reversed/3, + brachylog_order/3, brachylog_order_reversed/3, + brachylog_permute/3, brachylog_permute_reversed/3, + brachylog_substring/3, brachylog_substring_reversed/3, + brachylog_tail/3, brachylog_tail_reversed/3, + brachylog_write/3, brachylog_write_reversed/3, + brachylog_xterminate/3, brachylog_xterminate_reversed/3, + brachylog_zip/3, brachylog_zip_reversed/3, + + %Lowercase letters with dot below % Reversed version + brachylog_to_codes/3, brachylog_to_codes_reversed/3, + brachylog_blocks/3, brachylog_blocks_reversed/3, + brachylog_dichotomize/3, brachylog_dichotomize_reversed/3, + brachylog_elements/3, brachylog_elements_reversed/3, + brachylog_to_number/3, brachylog_to_number_reversed/3, + brachylog_lowercase/3, brachylog_lowercase_reversed/3, + brachylog_split_lines/3, brachylog_split_lines_reversed/3, + brachylog_occurences/3, brachylog_occurences_reversed/3, + brachylog_random_element/3, brachylog_random_element_reversed/3, + brachylog_shuffle/3, brachylog_shuffle_reversed/3, + brachylog_uppercase/3, brachylog_uppercase_reversed/3, + brachylog_writeln/3, brachylog_writeln_reversed/3, + + %Lowercase letters with dot above % Reversed version + brachylog_absolute_value/3, brachylog_absolute_value_reversed/3, + brachylog_base/3, brachylog_base_reversed/3, + brachylog_coerce/3, brachylog_coerce_reversed/3, + brachylog_prime_decomposition/3, brachylog_prime_decomposition_reversed/3, + brachylog_factorial/3, brachylog_factorial_reversed/3, + brachylog_groups/3, brachylog_groups_reversed/3, + brachylog_matrix/3, brachylog_matrix_reversed/3, + brachylog_negate/3, brachylog_negate_reversed/3, + brachylog_prime/3, brachylog_prime_reversed/3, + brachylog_random_number/3, brachylog_random_number_reversed/3, + brachylog_sign/3, brachylog_sign_reversed/3, + brachylog_to_string/3, brachylog_to_string_reversed/3, + brachylog_cartesian_product/3, brachylog_cartesian_product_reversed/3, + + %Label % Reversed version + brachylog_label/3, brachylog_label_reversed/3 + ]). + +:- use_module(library(clpfd)). +:- use_module(utils). + +:- multifile clpfd:run_propagator/2. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LESSEQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_lessequal_reversed(S, I, O) :- + brachylog_lessequal(S, O, I). +brachylog_lessequal('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_lessequal('integer':I, Arg, Output). +brachylog_lessequal('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_lessequal('integer':I, Arg, Output). +brachylog_lessequal('default', Input, Output) :- + brachylog_lessequal('integer':0, Input, Output). +brachylog_lessequal('integer':0, 'integer':I1, 'integer':I2) :- + I1 #=< I2. +brachylog_lessequal('integer':0, 'float':I1, 'integer':I2) :- + nonvar(I1), + brachylog_label('default', 'integer':I2, _), + I1 =< I2. +brachylog_lessequal('integer':0, 'integer':I1, 'float':I2) :- + nonvar(I2), + brachylog_label('default', 'integer':I1, _), + I1 =< I2. +brachylog_lessequal('integer':0, 'float':I1, 'float':I2) :- + nonvar(I1), + nonvar(I2), + I1 =< I2. +brachylog_lessequal('integer':1, [], []). +brachylog_lessequal('integer':1, [I], [I]). +brachylog_lessequal('integer':1, [I,J|T], [I,J|T]) :- + brachylog_lessequal('integer':0, I, J), + brachylog_lessequal('integer':1, [J|T], [J|T]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GREATEREQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_greaterequal_reversed(S, I, O) :- + brachylog_greaterequal(S, O, I). +brachylog_greaterequal('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_greaterequal('integer':I, Arg, Output). +brachylog_greaterequal('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_greaterequal('integer':I, Arg, Output). +brachylog_greaterequal('default', Input, Output) :- + brachylog_greaterequal('integer':0, Input, Output). +brachylog_greaterequal('integer':0, 'integer':I1, 'integer':I2) :- + I1 #>= I2. +brachylog_greaterequal('integer':0, 'float':I1, 'integer':I2) :- + nonvar(I1), + brachylog_label('default', 'integer':I2, _), + I1 >= I2. +brachylog_greaterequal('integer':0, 'integer':I1, 'float':I2) :- + nonvar(I2), + brachylog_label('default', 'integer':I1, _), + I1 >= I2. +brachylog_greaterequal('integer':0, 'float':I1, 'float':I2) :- + nonvar(I1), + nonvar(I2), + I1 >= I2. +brachylog_greaterequal('integer':1, [], []). +brachylog_greaterequal('integer':1, [I], [I]). +brachylog_greaterequal('integer':1, [I,J|T], [I,J|T]) :- + brachylog_greaterequal('integer':0, I, J), + brachylog_greaterequal('integer':1, [J|T], [J|T]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CONTAINS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_contains_reversed(S, I, O) :- + brachylog_contains(S, O, I). +brachylog_contains(Sub, Input, Output) :- + brachylog_in(Sub, Output, Input). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_IN +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_in_reversed(S, I, O) :- + brachylog_in(S, O, I). +brachylog_in('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_in('integer':I, Arg, Output). +brachylog_in('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_in('integer':I, Arg, Output). +brachylog_in('default', 'string':L, 'string':[M]) :- + nth0(_, L, M). +brachylog_in('integer':S, 'string':L, 'string':[M]) :- + nth0(S, L, M). +brachylog_in('default', 'integer':0, 'integer':0). +brachylog_in('integer':0, 'integer':0, 'integer':0). +brachylog_in('default', 'integer':I, 'integer':J) :- + H #\= 0, + integer_value('integer':_:[H|T], I), + nth0(_, [H|T], M), + integer_value('integer':'positive':[M], J). +brachylog_in('integer':S, 'integer':I, 'integer':J) :- + H #\= 0, + integer_value('integer':_:[H|T], I), + nth0(S, [H|T], M), + integer_value('integer':'positive':[M], J). +brachylog_in('default', L, M) :- + is_brachylog_list(L), + nth0(_, L, M). +brachylog_in('integer':S, L, M) :- + is_brachylog_list(L), + nth0(S, L, M). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SUPERSET +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_superset_reversed(S, I, O) :- + brachylog_superset(S, O, I). +brachylog_superset(Sub, Input, Output) :- + brachylog_subset(Sub, Output, Input). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SUBSET +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_subset_reversed(S, I, O) :- + brachylog_subset(S, O, I). +brachylog_subset('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_subset('integer':I, Arg, Output). +brachylog_subset('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_subset('integer':I, Arg, Output). +brachylog_subset('default', Input, Output) :- + brachylog_subset('integer':0, Input, Output). +brachylog_subset('integer':0, 'string':S, 'string':T) :- + brachylog_subset_recur(S, T). +brachylog_subset('integer':0, 'integer':0, 'integer':0). +brachylog_subset('integer':0, 'integer':I, 'integer':J) :- + H #\= 0, + dif(M, []), + integer_value('integer':Sign:[H|L], I), + brachylog_subset_recur([H|L], M), + integer_value('integer':Sign:M, J). +brachylog_subset('integer':0, 'float':F, 'float':G) :- + Sign is abs(F)/F, + AF is abs(F), + number_chars(AF, C), + brachylog_subset_recur(C, D), + dif(D, []), + \+ (D = ['.'|_] ; reverse(D, ['.'|_])), + number_chars(AG,D), + G is Sign*AG. +brachylog_subset('integer':0, L, S) :- + is_brachylog_list(L), + brachylog_subset_recur(L, S). + +brachylog_subset_recur(L, S) :- + var(S), + length(L, Length), + between(0, Length, I), + J #= Length - I, + length(S, J), + brachylog_subset_recur_(L, S). +brachylog_subset_recur(L, S) :- + nonvar(S), + length(S, Length), + I #>= Length, + length(L, I), + brachylog_subset_recur_(L, S). + +brachylog_subset_recur_([], []). +brachylog_subset_recur_([H|T], [H|T2]) :- + brachylog_subset_recur_(T, T2). +brachylog_subset_recur_([_|T], T2) :- + brachylog_subset_recur_(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_REVERSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_reverse_reversed(S, I, O) :- + brachylog_reverse(S, O, I). +brachylog_reverse('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_reverse('integer':I, Arg, Output). +brachylog_reverse('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_reverse('integer':I, Arg, Output). +brachylog_reverse('default', Input, Output) :- + brachylog_reverse('integer':0, Input, Output). +brachylog_reverse('integer':0, 'string':S, 'string':R) :- + reverse(S, R). +brachylog_reverse('integer':0, 'integer':I, 'integer':R) :- + nonvar(I), + H #\= 0, + A #\= 0, + integer_value('integer':Sign:[H|T], I), + reverse([H|T], B), + append(Zeroes, [A|Rest], B), + maplist(=(0), Zeroes), + integer_value('integer':Sign:[A|Rest], R). +brachylog_reverse('integer':0, 'integer':0, 'integer':0). +brachylog_reverse('integer':0, 'integer':I, 'integer':R) :- + var(I), + H #\= 0, + A #\= 0, + integer_value('integer':Sign:[A|B], R), + reverse(L, [A|B]), + append(Zeroes, [H|T], L), + maplist(=(0), Zeroes), + integer_value('integer':Sign:[H|T], I). +brachylog_reverse('integer':0, List, R) :- + reverse(List, R). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CALL_PREDICATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_call_predicate_reversed(S, I, O) :- + brachylog_call_predicate(S, O, I). +brachylog_call_predicate('first'-GlobalVariables, ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output). +brachylog_call_predicate('last'-GlobalVariables, Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_call_predicate(GlobalVariables, 'integer':I, Arg, Output). +brachylog_call_predicate(Name-GlobalVariables, Arg, Output) :- + brachylog_call_predicate(GlobalVariables, Name, Arg, Output). +brachylog_call_predicate(GlobalVariables, CallingPredName, Input, Output) :- + atom(CallingPredName), + call(CallingPredName, GlobalVariables, 'integer':0, Input, Output). +brachylog_call_predicate(GlobalVariables, 'integer':I, Input, Output) :- + ( I = 0, + PredName = 'brachylog_main' + ; I #> 0, + atomic_list_concat(['brachylog_predicate_',I], PredName) + ), + call(PredName, GlobalVariables, 'integer':0, Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CIRCULAR_PERMUTE_COUNTERCLOCKWISE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_circular_permute_counterclockwise_reversed(S, I, O) :- + brachylog_circular_permute_counterclockwise(S, O, I). +brachylog_circular_permute_counterclockwise('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_circular_permute_counterclockwise('integer':I, Arg, Output). +brachylog_circular_permute_counterclockwise('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_circular_permute_counterclockwise('integer':I, Arg, Output). +brachylog_circular_permute_counterclockwise('default', Input, Output) :- + brachylog_circular_permute_counterclockwise('integer':1, Input, Output). +brachylog_circular_permute_counterclockwise('integer':0, Input, Input). +brachylog_circular_permute_counterclockwise('integer':1, 'string':[], 'string':[]). +brachylog_circular_permute_counterclockwise('integer':1, 'string':[H|T], 'string':S) :- + append(T, [H], S). +brachylog_circular_permute_counterclockwise('integer':1, [], []). +brachylog_circular_permute_counterclockwise('integer':1, [H|T], S) :- + append(T, [H], S). +brachylog_circular_permute_counterclockwise('integer':1, 'integer':0, 'integer':0). +brachylog_circular_permute_counterclockwise('integer':1, 'integer':I, 'integer':J) :- + dif(H, 0), + integer_value('integer':Sign:[H|T], I), + append(T, [H], S), + integer_value('integer':Sign:S, J). +brachylog_circular_permute_counterclockwise('integer':I, Input, Output) :- + I #> 1, + brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_counterclockwise, 'default', Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CIRCULAR_PERMUTE_CLOCKWISE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_circular_permute_clockwise_reversed(S, I, O) :- + brachylog_circular_permute_clockwise(S, O, I). +brachylog_circular_permute_clockwise('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_circular_permute_clockwise('integer':I, Arg, Output). +brachylog_circular_permute_clockwise('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_circular_permute_clockwise('integer':I, Arg, Output). +brachylog_circular_permute_clockwise('default', Input, Output) :- + brachylog_circular_permute_clockwise('integer':1, Input, Output). +brachylog_circular_permute_clockwise('integer':0, Input, Input). +brachylog_circular_permute_clockwise('integer':1, 'string':[], 'string':[]). +brachylog_circular_permute_clockwise('integer':1, 'string':L, 'string':S) :- + append(T, [H], L), + S = [H|T]. +brachylog_circular_permute_clockwise('integer':1, [], []). +brachylog_circular_permute_clockwise('integer':1, [A|B], S) :- + append(T, [H], [A|B]), + S = [H|T]. +brachylog_circular_permute_clockwise('integer':1, 'integer':0, 'integer':0). +brachylog_circular_permute_clockwise('integer':1, 'integer':I, 'integer':J) :- + dif(H2, 0), + integer_value('integer':Sign:[H2|T2], I), + append(T, [H], [H2|T2]), + S = [H|T], + integer_value('integer':Sign:S, J). +brachylog_circular_permute_clockwise('integer':I, Input, Output) :- + I #> 1, + brachylog_meta_iterate(ignore, 'integer':I, brachylog_circular_permute_clockwise, 'default', Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ROOT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_root_reversed(S, I, O) :- + brachylog_root(S, O, I). +brachylog_root('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_root('integer':I, Arg, Output). +brachylog_root('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_root('integer':I, Arg, Output). +brachylog_root('default', Input, Output) :- + brachylog_root('integer':2, Input, Output). +brachylog_root('integer':I,'integer':E, Type:R) :- + ( E #= R^I -> + Type = 'integer' + ; brachylog_label('default', ['integer':I, 'integer':E], _), + R is E^(1/I), + Type = 'float' + ). +brachylog_root('integer':I,'float':E, 'float':R) :- + nonvar(E), + brachylog_label('default', 'integer':I, _), + R is E^(1/I). +brachylog_root('float':I,'integer':E, 'float':R) :- + brachylog_label('default', 'integer':E, _), + R is E^(1/I). +brachylog_root('float':I,'float':E, 'float':R) :- + nonvar(E), + R is E^(1/I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CEIL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_ceil_reversed(S, I, O) :- + brachylog_ceil(S, O, I). +brachylog_ceil('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_ceil('integer':I, Arg, Output). +brachylog_ceil('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_ceil('integer':I, Arg, Output). +brachylog_ceil('default', Input, Output) :- + brachylog_ceil('integer':0, Input, Output). +brachylog_ceil('integer':0, [H|T], Output) :- + foldl(scompare(@>), [H|T], H, Output). +brachylog_ceil('integer':1, 'integer':I, 'integer':I). +brachylog_ceil('integer':1, 'float':I, 'integer':J) :- + nonvar(I), + J is ceil(I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FLOOR +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_floor_reversed(S, I, O) :- + brachylog_floor(S, O, I). +brachylog_floor('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_floor('integer':I, Arg, Output). +brachylog_floor('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_floor('integer':I, Arg, Output). +brachylog_floor('default', Input, Output) :- + brachylog_floor('integer':0, Input, Output). +brachylog_floor('integer':0, [H|T], Output) :- + foldl(scompare(@<), [H|T], H, Output). +brachylog_floor('integer':1, 'integer':I, 'integer':I). +brachylog_floor('integer':1, 'float':I, 'integer':J) :- + nonvar(I), + J is floor(I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANGE_ASCENDING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_range_ascending_reversed(S, I, O) :- + brachylog_range_ascending(S, O, I). +brachylog_range_ascending('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_range_ascending('integer':I, Arg, Output). +brachylog_range_ascending('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_range_ascending('integer':I, Arg, Output). +brachylog_range_ascending('default', Input, Output) :- + brachylog_range_ascending('integer':0, Input, Output). +brachylog_range_ascending('integer':0, 'integer':Input, Output) :- + ( 0 #=< Input, + brachylog_range_ascending_(0, Input, Output) + ; 0 #> Input, + brachylog_range_ascending_(Input, 0, Output) + ). +brachylog_range_ascending('integer':1, 'integer':Input, Output) :- + ( 1 #=< Input, + brachylog_range_ascending_(1, Input, Output) + ; 1 #> Input, + brachylog_range_ascending_(Input, 1, Output) + ). +brachylog_range_ascending('integer':2, ['integer':X,'integer':Y], Output) :- + ( X #=< Y, + brachylog_range_ascending_(X, Y, Output) + ; X #> Y, + brachylog_range_ascending_(Y, X, Output) + ). +brachylog_range_ascending('integer':3, ['integer':X,'integer':Y], Output) :- + ( X #=< Y, + Y2 #= Y - 1, + brachylog_range_ascending_(X, Y2, Output) + ; X #> Y, + X2 #= X - 1, + brachylog_range_ascending_(Y, X2, Output) + ). +brachylog_range_ascending('integer':4, ['integer':X,'integer':Y], Output) :- + ( X #=< Y, + X2 #= X + 1, + brachylog_range_ascending_(X2, Y, Output) + ; X #> Y, + Y2 #= Y + 1, + brachylog_range_ascending_(Y2, X, Output) + ). +brachylog_range_ascending('integer':5, 'integer':Input, Output) :- + ( 0 #=< Input, + I2 #= Input - 1, + brachylog_range_ascending_(0, I2, Output) + ; 0 #> Input, + I2 #= Input + 1, + brachylog_range_ascending_(I2, 0, Output) + ). +brachylog_range_ascending('integer':6, 'integer':Input, Output) :- + ( 1 #=< Input, + I2 #= Input - 1, + brachylog_range_ascending_(1, I2, Output) + ; 1 #> Input, + I2 #= Input + 1, + brachylog_range_ascending_(I2, 1, Output) + ). + +brachylog_range_ascending_(I, S, ['integer':I|R]) :- + I #=< S, + if_(I = S, + R = [], + ( J #= I + 1, + predicates:brachylog_range_ascending_(J, S, R) + ) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANGE_DESCENDING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_range_descending_reversed(S, I, O) :- + brachylog_range_descending(S, O, I). +brachylog_range_descending('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_range_descending('integer':I, Arg, Output). +brachylog_range_descending('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_range_descending('integer':I, Arg, Output). +brachylog_range_descending('default', Input, Output) :- + brachylog_range_descending('integer':0, Input, Output). +brachylog_range_descending('integer':Sub, Input, Output) :- + brachylog_range_ascending('integer':Sub, Input, ROutput), + brachylog_reverse('default', ROutput, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_NATURAL_INTEGER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_natural_integer_reversed(S, I, O) :- + brachylog_natural_integer(S, O, I). +brachylog_natural_integer('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_natural_integer('integer':I, Arg, Output). +brachylog_natural_integer('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_natural_integer('integer':I, Arg, Output). +brachylog_natural_integer('default', Input, Output) :- + brachylog_natural_integer('integer':0, Input, Output). +brachylog_natural_integer('integer':I, 'integer':Input, 'integer':Input) :- + I #>= 0, + Input #>= I. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_INTEGER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_integer_reversed(S, I, O) :- + brachylog_integer(S, O, I). +brachylog_integer('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_integer('integer':I, Arg, Output). +brachylog_integer('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_integer('integer':I, Arg, Output). +brachylog_integer('default', 'integer':Input, 'integer':Input) :- + Input in inf..sup. +brachylog_integer('integer':I, 'integer':Input, 'integer':Input) :- + I #>= 0, + Input #=< -I. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FLOAT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_float_reversed(S, I, O) :- + brachylog_float(S, O, I). +brachylog_float('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_float('integer':I, Arg, Output). +brachylog_float('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_float('integer':I, Arg, Output). +brachylog_float('default', 'float':Input, 'float':Input). +brachylog_float('integer':_, 'integer':Input, 'float':Input). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DIFFERENT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_different_reversed(S, I, O) :- + brachylog_different(S, O, I). +brachylog_different('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_different('integer':I, Arg, Output). +brachylog_different('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_different('integer':I, Arg, Output). +brachylog_different('default', 'string':S, 'string':S) :- + brachylog_different_(S). +brachylog_different('default', [], []). +brachylog_different('default', [H|T], [H|T]) :- + ( maplist(prepend_integer, L, [H|T]), + all_different(L) % More efficient on integers + ; maplist(prepend_string, _, [H|T]), + brachylog_different_([H|T]) + ; maplist(is_brachylog_list, [H|T]), + brachylog_different_([H|T]) + ). +brachylog_different('default', 'integer':I, 'integer':I) :- + ( integer_value('integer':_:[_], I) -> + true + ; H #\= 0, + integer_value('integer':_:[H,H2|T], I), + all_different([H,H2|T]) + ). + +brachylog_different_([]). +brachylog_different_([H|T]) :- + maplist(dif(H), T), + brachylog_different_(T). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_IDENTITY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_identity_reversed(S, I, O) :- + brachylog_identity(S, O, I). +brachylog_identity(_, Input, Input). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_INTEGER_DIVISION +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_integer_division_reversed(S, I, O) :- + brachylog_integer_division(S, O, I). +brachylog_integer_division('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_integer_division('integer':I, Arg, Output). +brachylog_integer_division('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_integer_division('integer':I, Arg, Output). +brachylog_integer_division('default', Input, Output) :- + brachylog_integer_division('integer':0, Input, Output). +brachylog_integer_division('integer':0, [], 'integer':1). +brachylog_integer_division('integer':0, ['integer':I1,'integer':I2], 'integer':Division) :- + brachylog_label('default', ['integer':I1,'integer':I2], _), + Division #= I1 // I2. +brachylog_integer_division('integer':0, ['float':I1,'integer':I2], 'integer':Division) :- + brachylog_label('default', 'integer':I2, _), + nonvar(I1), + D is I1 / I2, + brachylog_floor('integer':1, 'float':D, 'integer':Division). +brachylog_integer_division('integer':0, ['integer':I1,'float':I2], 'integer':Division) :- + brachylog_label('default', 'integer':I1, _), + nonvar(I2), + D is I1 / I2, + brachylog_floor('integer':1, 'float':D, 'integer':Division). +brachylog_integer_division('integer':0, ['float':I1,'float':I2], 'integer':Division) :- + nonvar(I1), + nonvar(I2), + D is I1 / I2, + brachylog_floor('integer':1, 'float':D, 'integer':Division). +brachylog_integer_division('integer':I, Input, Output) :- + I #> 0, + brachylog_integer_division('integer':0, [Input,'integer':I], Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MULTIPLY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_multiply_reversed(S, I, O) :- + brachylog_multiply(S, O, I). +brachylog_multiply('first', ['integer':A,'integer':B], Output) :- + brachylog_multiply('integer':A, 'integer':B, Output). +brachylog_multiply('last', ['integer':A,'integer':B], Output) :- + brachylog_multiply('integer':B, 'integer':A, Output). +brachylog_multiply('integer':S, 'integer':I, 'integer':J) :- + J #= S*I. +brachylog_multiply('integer':S, 'float':F, 'float':G) :- + nonvar(F), + G is S*F. +brachylog_multiply('default', [], 'integer':1). +brachylog_multiply('default', [TypeI:I|T], TypeS:Product) :- + ( TypeI = 'integer', + TypeF = 'integer', + ( var(I) -> + I #> 0, + F #> 0 + ; true + ), + Product #= I * F, + TypeS = 'integer', + brachylog_multiply('default', T, TypeF:F) + ; TypeS = 'float', + brachylog_multiply('default', T, TypeF:F), + ( TypeF = 'float', + TypeI = 'integer', + brachylog_label('default', 'integer':I, _) + ; TypeI = 'float', + nonvar(I), + TypeF = 'integer', + brachylog_label('default', 'integer':F, _) + ; TypeF = 'float', + TypeI = 'float', + nonvar(I) + ), + Product is I * F + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MODULO +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_modulo_reversed(S, I, O) :- + brachylog_modulo(S, O, I). +brachylog_modulo('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_modulo('integer':I, Arg, Output). +brachylog_modulo('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_modulo('integer':I, Arg, Output). +brachylog_modulo('default', Input, Output) :- + brachylog_modulo('integer':0, Input, Output). +brachylog_modulo('integer':0, ['integer':I1,'integer':I2], 'integer':Rem) :- + Rem #= I1 mod I2. +brachylog_modulo('integer':I, 'integer':I1, 'integer':Rem) :- + I #> 0, + Rem #= I1 mod I. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_EXP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_exp_reversed(S, I, O) :- + brachylog_exp(S, O, I). +brachylog_exp('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_exp('integer':I, Arg, Output). +brachylog_exp('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_exp('integer':I, Arg, Output). +brachylog_exp('default', Input, Output) :- + brachylog_exp('integer':0, Input, Output). +brachylog_exp('integer':0, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is exp(I). +brachylog_exp('integer':0, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is exp(F). +brachylog_exp('integer':1, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is log(I). +brachylog_exp('integer':1, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is log(F). +brachylog_exp('integer':2, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is cos(I). +brachylog_exp('integer':2, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is cos(F). +brachylog_exp('integer':3, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is sin(I). +brachylog_exp('integer':3, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is sin(F). +brachylog_exp('integer':4, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is tan(I). +brachylog_exp('integer':4, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is tan(F). +brachylog_exp('integer':5, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is acos(I). +brachylog_exp('integer':5, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is acos(F). +brachylog_exp('integer':6, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is asin(I). +brachylog_exp('integer':6, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is asin(F). +brachylog_exp('integer':7, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is atan(I). +brachylog_exp('integer':7, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is atan(F). +brachylog_exp('integer':8, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is cosh(I). +brachylog_exp('integer':8, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is cosh(F). +brachylog_exp('integer':9, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is sinh(I). +brachylog_exp('integer':9, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is sinh(F). +brachylog_exp('integer':10, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is tanh(I). +brachylog_exp('integer':10, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is tanh(F). +brachylog_exp('integer':11, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is acosh(I). +brachylog_exp('integer':11, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is acosh(F). +brachylog_exp('integer':12, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is asinh(I). +brachylog_exp('integer':12, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is asinh(F). +brachylog_exp('integer':13, 'integer':I, 'float':Exp) :- + brachylog_label('default', 'integer':I, _), + Exp is atanh(I). +brachylog_exp('integer':13, 'float':F, 'float':Exp) :- + nonvar(F), + Exp is atanh(F). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PLUS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_plus_reversed(S, I, O) :- + brachylog_plus(S, O, I). +brachylog_plus('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_plus('integer':I, Arg, Output). +brachylog_plus('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_plus('integer':I, Arg, Output). +brachylog_plus('default', Input, Output) :- + brachylog_plus('integer':0, Input, Output). +brachylog_plus('integer':I, 'integer':Input, 'integer':Output) :- + I #> 0, + Output #= Input + I. +brachylog_plus('integer':I, 'float':Input, 'float':Output) :- + I #> 0, + nonvar(Input), + Output is Input + I. +brachylog_plus('integer':0, [], 'integer':0). +brachylog_plus('integer':0, [TypeI:I|T], TypeS:Sum) :- + brachylog_plus('integer':0, T, TypeF:F), + ( TypeI = 'integer', + TypeF = 'integer', + Sum #= I + F, + TypeS = 'integer' + ; TypeS = 'float', + ( TypeF = 'float', + TypeI = 'integer', + brachylog_label('default', 'integer':I, _) + ; TypeI = 'float', + nonvar(I), + TypeF = 'integer', + brachylog_label('default', 'integer':F, _) + ; TypeF = 'float', + TypeI = 'float', + nonvar(I) + ), + Sum is I + F + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MINUS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_minus_reversed(S, I, O) :- + brachylog_minus(S, O, I). +brachylog_minus('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_minus('integer':I, Arg, Output). +brachylog_minus('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_minus('integer':I, Arg, Output). +brachylog_minus('default', Input, Output) :- + brachylog_minus('integer':0, Input, Output). +brachylog_minus('integer':I, 'integer':Input, 'integer':Output) :- + I #> 0, + Output #= Input - I. +brachylog_minus('integer':I, 'float':Input, 'float':Output) :- + I #> 0, + nonvar(Input), + Output is Input - I. +brachylog_minus('integer':0, [], 'integer':0). +brachylog_minus('integer':0, [TypeI:I|T], TypeS:Sum) :- + brachylog_minus('integer':0, T, TypeF:F), + ( TypeI = 'integer', + TypeF = 'integer', + Sum #= I - F, + TypeS = 'integer' + ; TypeS = 'float', + ( TypeF = 'float', + TypeI = 'integer', + brachylog_label('default', 'integer':I, _) + ; TypeI = 'float', + nonvar(I), + TypeF = 'integer', + brachylog_label('default', 'integer':F, _) + ; TypeF = 'float', + TypeI = 'float', + nonvar(I) + ), + Sum is I - F + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DIVIDE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_divide_reversed(S, I, O) :- + brachylog_divide(S, O, I). +brachylog_divide('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_divide('integer':I, Arg, Output). +brachylog_divide('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_divide('integer':I, Arg, Output). +brachylog_divide('default', [], 'integer':1). +brachylog_divide('default', ['integer':I1,'integer':I2], Type:Division) :- + brachylog_label('default', ['integer':I1,'integer':I2], _), + I2 #\= 0, + Division is I1 / I2, + ( integer(Division) -> + Type = 'integer' + ; Type = 'float' + ). +brachylog_divide('default', ['integer':0, 'integer':0], 'integer':_). +brachylog_divide('default', ['float':I1,'integer':I2], 'float':Division) :- + brachylog_label('default', 'integer':I2, _), + I2 #\= 0, + nonvar(I1), + Division is I1 / I2. +brachylog_divide('default', ['float':0.0, 'integer':0], 'float':_). +brachylog_divide('default', ['integer':I1,'float':I2], 'float':Division) :- + brachylog_label('default', 'integer':I1, _), + nonvar(I2), + dif(I2, 0.0), + Division is I1 / I2. +brachylog_divide('default', ['integer':0, 'float':0.0], 'float':_). +brachylog_divide('default', ['float':I1,'float':I2], 'float':Division) :- + nonvar(I1), + nonvar(I2), + dif(I2, 0.0), + Division is I1 / I2. +brachylog_divide('default', ['float':0.0, 'float':0.0], 'float':_). +brachylog_divide('integer':1, 'integer':I, 'float':J) :- + brachylog_label('default', 'integer':I, _), + J is 1/I. +brachylog_divide('integer':1, 'float':I, 'float':J) :- + J is 1/I. +brachylog_divide('integer':I, Input, Output) :- + I #> 1, + brachylog_divide('default', [Input,'integer':I], Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LESS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_less_reversed(S, I, O) :- + brachylog_less(S, O, I). +brachylog_less('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_less('integer':I, Arg, Output). +brachylog_less('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_less('integer':I, Arg, Output). +brachylog_less('default', Input, Output) :- + brachylog_less('integer':0, Input, Output). +brachylog_less('integer':0, 'integer':I1, 'integer':I2) :- + I1 #< I2. +brachylog_less('integer':0, 'float':I1, 'integer':I2) :- + nonvar(I1), + brachylog_label('default', 'integer':I2, _), + I1 < I2. +brachylog_less('integer':0, 'integer':I1, 'float':I2) :- + nonvar(I2), + brachylog_label('default', 'integer':I1, _), + I1 < I2. +brachylog_less('integer':0, 'float':I1, 'float':I2) :- + nonvar(I1), + nonvar(I2), + I1 < I2. +brachylog_less('integer':1, [], []). +brachylog_less('integer':1, [I], [I]). +brachylog_less('integer':1, [I,J|T], [I,J|T]) :- + brachylog_less('integer':0, I, J), + brachylog_less('integer':1, [J|T], [J|T]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_EQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_equal_reversed(S, I, O) :- + brachylog_equal(S, O, I). +brachylog_equal('first', [I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_equal(I, Arg, Output). +brachylog_equal('last', Input, Output) :- + reverse(Input, [I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_equal(I, Arg, Output). +brachylog_equal('default', [], []). +brachylog_equal('default', [H|T], [H|T]) :- + maplist(=(H), T). +brachylog_equal('default', 'string':L, 'string':L) :- + brachylog_equal('integer':0, L, L). +brachylog_equal('default', 'integer':0, 'integer':0). +brachylog_equal('default', 'integer':I, 'integer':I) :- + H #\= 0, + integer_value('integer':_:[H|T], I), + brachylog_equal('default', [H|T], [H|T]). +brachylog_equal(Type:I, [Type:I|T], [Type:I|T]) :- + brachylog_equal('default', [Type:I|T], [Type:I|T]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GREATER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_greater_reversed(S, I, O) :- + brachylog_greater(S, O, I). +brachylog_greater('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_greater('integer':I, Arg, Output). +brachylog_greater('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_greater('integer':I, Arg, Output). +brachylog_greater('default', Input, Output) :- + brachylog_greater('integer':0, Input, Output). +brachylog_greater('integer':0, 'integer':I1, 'integer':I2) :- + I1 #> I2. +brachylog_greater('integer':0, 'float':I1, 'integer':I2) :- + nonvar(I1), + brachylog_label('default', 'integer':I2, _), + I1 > I2. +brachylog_greater('integer':0, 'integer':I1, 'float':I2) :- + nonvar(I2), + brachylog_label('default', 'integer':I1, _), + I1 > I2. +brachylog_greater('integer':0, 'float':I1, 'float':I2) :- + nonvar(I1), + nonvar(I2), + I1 > I2. +brachylog_greater('integer':1, [], []). +brachylog_greater('integer':1, [I], [I]). +brachylog_greater('integer':1, [I,J|T], [I,J|T]) :- + brachylog_greater('integer':0, I, J), + brachylog_greater('integer':1, [J|T], [J|T]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TRANSPOSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_transpose_reversed(S, I, O) :- + brachylog_transpose(S, O, I). +brachylog_transpose('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_transpose('integer':I, Arg, Output). +brachylog_transpose('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_transpose('integer':I, Arg, Output). +brachylog_transpose('default', Input, Output) :- + brachylog_transpose('integer':0, Input, Output). +brachylog_transpose('integer':0, 'string':Input, 'string':Output) :- + brachylog_split_lines('default', Input, Ls), + brachylog_elements('default', Ls, LLs), + brachylog_transpose('integer':0, LLs, CCs), + maplist(brachylog_concatenate('default'), CCs, Cs), + brachylog_split_lines('default', Output, Cs). +brachylog_transpose('integer':0, Input, Output) :- + is_brachylog_list(Input), + member(X, Input), + is_list(X), + !, + maplist(is_brachylog_list, Input), + length(X, LX), + length(Input, LI), + brachylog_juxtapose('integer':LI, ['integer':LX], Lengths), + maplist(brachylog_length('default'), Input, Lengths), + brachylog_equal('default', Lengths, _), + transpose(Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_POWER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_power_reversed(S, I, O) :- + brachylog_power(S, O, I). +brachylog_power('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_power('integer':I, Arg, Output). +brachylog_power('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_power('integer':I, Arg, Output). +brachylog_power('default', [], 'integer':1). +brachylog_power('default', ['integer':I1,'integer':I2], 'integer':Power) :- + Power #= I1 ^ I2. +brachylog_power('default', ['float':I1,'integer':I2], 'float':Power) :- + nonvar(I1), + brachylog_label('default', 'integer':I2, _), + Power is I1 ^ I2. +brachylog_power('default', ['integer':I1,'float':I2], 'float':Power) :- + nonvar(I2), + brachylog_label('default', 'integer':I1, _), + Power is I1 ^ I2. +brachylog_power('default', ['float':I1,'float':I2], 'float':Power) :- + nonvar(I1), + nonvar(I2), + Power is I1 ^ I2. +brachylog_power('integer':S, 'integer':I, 'integer':J) :- + J #= I^S. +brachylog_power('integer':S, 'float':I, 'float':J) :- + nonvar(I), + brachylog_label('default', 'integer':S, _), + J is I^S. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ADFIX +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_adfix_reversed(S, I, O) :- + brachylog_adfix(S, O, I). +brachylog_adfix('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_adfix('integer':I, Arg, Output). +brachylog_adfix('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_adfix('integer':I, Arg, Output). +brachylog_adfix('default', Input, Output) :- + ( brachylog_adfix('integer':0, Input, Output) + ; brachylog_adfix('integer':1, Input, Output) + ). +brachylog_adfix('integer':0, [], []). +brachylog_adfix('integer':0, [H|T], [H2|T2]) :- + ( brachylog_concatenate('default', [[H2|T2],[_|_]], [H|T]) + ; [H2|T2] = [H|T] + ). +brachylog_adfix('integer':0, 'string':S, 'string':P) :- + brachylog_adfix('integer':0, S, P). +brachylog_adfix('integer':0, 'integer':0, 'integer':0). +brachylog_adfix('integer':0, 'integer':I, 'integer':P) :- + H #\= 0, + H2 #\= 0, + abs(P) #=< abs(I), + integer_value('integer':Sign:[H|T], I), + integer_value('integer':Sign:[H2|T2], P), + brachylog_adfix('integer':0, [H|T], [H2|T2]). +brachylog_adfix('integer':1, [], []). +brachylog_adfix('integer':1, [H|T], [H2|T2]) :- + brachylog_concatenate('default', [_,[H2|T2]], [H|T]). +brachylog_adfix('integer':1, 'string':S, 'string':P) :- + brachylog_adfix('integer':1, S, P). +brachylog_adfix('integer':1, 'integer':0, 'integer':0). +brachylog_adfix('integer':1, 'integer':I, 'integer':P) :- + H #\= 0, + H2 #\= 0, + abs(P) #=< abs(I), + integer_value('integer':Sign:[H|T], I), + integer_value('integer':Sign:[H2|T2], P), + brachylog_adfix('integer':1, [H|T], [H2|T2]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_BEHEAD +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_behead_reversed(S, I, O) :- + brachylog_behead(S, O, I). +brachylog_behead('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_behead('integer':I, Arg, Output). +brachylog_behead('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_behead('integer':I, Arg, Output). +brachylog_behead('integer':0, Input, Input). +brachylog_behead('default', Input, Output) :- + brachylog_behead('integer':1, Input, Output). +brachylog_behead('integer':1, 'string':[_|T], 'string':T). +brachylog_behead('integer':1, 'integer':0, 'integer':0). +brachylog_behead('integer':1, 'integer':I, 'integer':J) :- + H #\= 0, + integer_value('integer':Sign:[H|T], I), + integer_value('integer':Sign:T, J). +brachylog_behead('integer':1, 'float':F,'float':G) :- + number_codes(F,L), + brachylog_behead_float(L,M), + number_codes(G,M). +brachylog_behead('integer':1, [_|T],T). +brachylog_behead('integer':I, Input, Output) :- + I #> 1, + brachylog_meta_iterate(ignore, 'integer':I, brachylog_behead, 'integer':1, Input, Output). + +brachylog_behead_float([], []). +brachylog_behead_float([48|T], [48|T2]) :- + brachylog_behead_float(T, T2). +brachylog_behead_float([46|T], [46|T2]) :- + brachylog_behead_float(T, T2). +brachylog_behead_float([H|T], [48|T2]) :- + H \= 46, + H \= 48, + brachylog_behead_float_(T, T2). + +brachylog_behead_float_([], []). +brachylog_behead_float_([H|T], [H|T2]) :- + brachylog_behead_float_(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CONCATENATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_concatenate_reversed(S, I, O) :- + brachylog_concatenate(S, O, I). +brachylog_concatenate('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_concatenate('integer':I, Arg, Output). +brachylog_concatenate('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_concatenate('integer':I, Arg, Output). +brachylog_concatenate('default', Input, Output) :- + brachylog_concatenate('integer':0, Input, Output). +brachylog_concatenate('integer':I, Input, Output) :- + I #> 0, + length(Input, I), + brachylog_concatenate('integer':0, Input, Output). +brachylog_concatenate('integer':0, [], []). +brachylog_concatenate('integer':0, [H|T],L) :- + var(L), + ( maplist(is_brachylog_list, [H|T]), + brachylog_coerce('default', L, L), + List = L, + ListOfLists = [H|T], + Integers = 'no' + ; maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T]), + brachylog_coerce('integer':2, 'string':List, L), + Integers = 'no' + ; maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T]), + Integers = 'yes' + ), + brachylog_concatenate_(ListOfLists, List), + ( Integers = 'yes', + List = [0], + L = 'integer':0 + ; Integers = 'yes', + List = [J|TList], + integer_value('integer':'positive':[J|TList], I), + L = 'integer':I + ; Integers = 'no' + ). +brachylog_concatenate('integer':0, [H|T], L) :- + nonvar(L), + brachylog_length('default', L, 'integer':Length), + ( var(T) -> + LengthList #> 0, + LengthList #=< Length, + indomain(LengthList), + length([H|T], LengthList), + CanContainEmpty = 'no' + ; CanContainEmpty = 'yes' + ), + ( is_brachylog_list(L), + maplist(brachylog_coerce('default'), [H|T], [H|T]), + List = L, + ListOfLists = [H|T] + ; L = 'string':List, + maplist(brachylog_concatenate_prepend_string_or_empty, ListOfLists, [H|T]) + ; L = 'integer':I, + ( I = 0, + List = [0] + ; I #\= 0, + J #\= 0, + integer_value('integer':_:[J|TList], I), + List = [J|TList] + ), + ( + CanContainEmpty = 'no' -> + maplist(brachylog_concatenate_limit_length(1, Length), [H|T]) + ; maplist(brachylog_concatenate_limit_length(0, Length), [H|T]) + ), + maplist(brachylog_concatenate_integer_value, ListOfLists, [H|T]) + ), + ( + CanContainEmpty = 'no' -> + maplist(brachylog_concatenate_limit_length(1, Length), [H|T]) + ; maplist(brachylog_concatenate_limit_length(0, Length), [H|T]) + ), + brachylog_concatenate_(ListOfLists, List). + +brachylog_concatenate_prepend_string_or_empty([], []). +brachylog_concatenate_prepend_string_or_empty(S, 'string':S). + +brachylog_concatenate_limit_length(Min, Max, H) :- + Length #>= Min, + Length #=< Max, + indomain(Length), + brachylog_length('default', H, 'integer':Length). + +brachylog_concatenate_integer_value([0], 'integer':0). +brachylog_concatenate_integer_value([], []). +brachylog_concatenate_integer_value([H|T], 'integer':I) :- + H #\= 0, + integer_value('integer':_:[H|T], I). + +brachylog_concatenate_([L|T], L2) :- + is_brachylog_list(L2), + append([L|T], L2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DUPLICATES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_duplicates_reversed(S, I, O) :- + brachylog_duplicates(S, O, I). +brachylog_duplicates('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_duplicates('integer':I, Arg, Output). +brachylog_duplicates('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_duplicates('integer':I, Arg, Output). +brachylog_duplicates('default', Input, Output) :- + brachylog_duplicates('integer':0, Input, Output). +brachylog_duplicates('integer':0, 'string':S, 'string':T) :- + list_to_set(S, T). +brachylog_duplicates('integer':0, 'integer':I, 'integer':J) :- + brachylog_label('default', 'integer':I, 'integer':I), + number_codes(I, C), + list_to_set(C, S), + number_codes(J, S). +brachylog_duplicates('integer':0, 'float':F, 'float':G) :- + number_codes(F, C), + list_to_set(C, S), + number_codes(G, S). +brachylog_duplicates('integer':0, L, M) :- + is_brachylog_list(L), + list_to_set(L, M). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FACTORS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_factors_reversed(S, I, O) :- + brachylog_factors(S, O, I). +brachylog_factors('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_factors('integer':I, Arg, Output). +brachylog_factors('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_factors('integer':I, Arg, Output). +brachylog_factors('default', 'integer':N, Z) :- + brachylog_label('default', 'integer':N, _), + ( N = 0 , + Z = [] + ; N #> 0, + findall('integer':X, (X #>= 1, X #=< N, I #>= 1, I #=< N, N #= X*I, indomain(X)), Z) + ; N #< 0, + findall('integer':X, (X #=< -1, X #>= N, I #>= 1, I #=< abs(N), N #= X*I, labeling([max(X)], [X])), Z) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GROUP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_group_reversed(S, I, O) :- + brachylog_group(S, O, I). +brachylog_group('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_group('integer':I, Arg, Output). +brachylog_group('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_group('integer':I, Arg, Output). +brachylog_group('integer':0, Input, Input). +brachylog_group('default', Input, Output) :- + brachylog_group('integer':1, Input, Output). +brachylog_group('integer':1, X, [X]). +brachylog_group('integer':I, Input, Output) :- + I #> 1, + brachylog_meta_iterate(ignore, 'integer':I, brachylog_group, 'integer':1, Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_HEAD +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_head_reversed(S, I, O) :- + brachylog_head(S, O, I). +brachylog_head('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_head('integer':I, Arg, Output). +brachylog_head('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_head('integer':I, Arg, Output). +brachylog_head('integer':0, _, []). +brachylog_head('default', 'string':[H|_], 'string':[H]). +brachylog_head('default', 'integer':0, 'integer':0). +brachylog_head('default', 'integer':I, 'integer':J) :- + J #\= 0, + integer_value('integer':_:[J|_], I). +brachylog_head('default', 'float':F, 'integer':I) :- + number_codes(F,L), + brachylog_head_float(L, 'integer':I). +brachylog_head('default', [H|_], H). +brachylog_head('integer':I, Input, Output) :- + I #> 0, + brachylog_length('default', Output, 'integer':I), + once(brachylog_concatenate('default', [Output, _], Input)). + +brachylog_head_float([H|T], 'integer':I) :- + ( ( H = 48 + ; H = 46 + ) -> + ( T = [], + I = 0 + ; T \= [], + brachylog_head_float(T, 'integer':I) + ) + ; H \= 48, + H \= 46, + number_codes(I, [H]) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_INDEX +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_index_reversed(S, I, O) :- + brachylog_index(S, I, O). +brachylog_index('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_index('integer':I, Arg, Output). +brachylog_index('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_index('integer':I, Arg, Output). +brachylog_index('default', Input, [E,'integer':I]) :- + brachylog_in('integer':I, Input, E). +brachylog_index('integer':1, Input, [E,'integer':J]) :- + J #= I + 1, + brachylog_in('integer':I, Input, E). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_JUXTAPOSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_juxtapose_reversed(S, I, O) :- + brachylog_juxtapose(S, O, I). +brachylog_juxtapose('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_juxtapose('integer':I, Arg, Output). +brachylog_juxtapose('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_juxtapose('integer':I, Arg, Output). +brachylog_juxtapose('default', Input, Output) :- + brachylog_juxtapose('integer':2, Input, Output). +brachylog_juxtapose('integer':_, [], []). +brachylog_juxtapose('integer':0, [_|_], []). +brachylog_juxtapose('integer':I, [H|T], Z) :- + var(Z), + Z = [HZ|TZ], + I #> 0, + length([H|T], L), + LZ #= I*L, + length([HZ|TZ], LZ), + append([H|T], T2, [HZ|TZ]), + J #= I-1, + brachylog_juxtapose('integer':J, [H|T], T2). +brachylog_juxtapose('integer':I, [H|T], Z) :- + nonvar(Z), + Z = [HZ|TZ], + I #> 0, + length([HZ|TZ], LZ), + LZ #= I*L, + indomain(L), + length([H|T], L), + append([H|T], T2, [HZ|TZ]), + J #= I-1, + brachylog_juxtapose('integer':J, [H|T], T2). +brachylog_juxtapose('integer':I, 'string':S, 'string':Z) :- + brachylog_juxtapose('integer':I, S, Z). +brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :- + var(Z), + dif(H, 0), + integer_value('integer':Sign:[H|T], I), + brachylog_juxtapose('integer':J, [H|T], LZ), + LZ = [HZ|_], + dif(HZ, 0), + integer_value('integer':Sign:LZ, Z). +brachylog_juxtapose('integer':J, 'integer':I, 'integer':Z) :- + nonvar(Z), + dif(H, 0), + dif(HZ, 0), + integer_value('integer':Sign:[HZ|TZ], Z), + brachylog_juxtapose('integer':J, [H|T], [HZ|TZ]), + integer_value('integer':Sign:[H|T], I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_KNIFE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_knife_reversed(S, I, O) :- + brachylog_knife(S, O, I). +brachylog_knife('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_knife('integer':I, Arg, Output). +brachylog_knife('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_knife('integer':I, Arg, Output). +brachylog_knife('integer':0, Input, Input). +brachylog_knife('default', Input, Output) :- + brachylog_knife('integer':1, Input, Output). +brachylog_knife('integer':1, [_], []). +brachylog_knife('integer':1, [H,I|T], [H2|T2]) :- + ( var(T) -> + reverse(T3, [H2|T2]), + reverse([H,I|T], [_|T3]) + ; reverse([H,I|T], [_|T3]), + reverse(T3, [H2|T2]) + ). +brachylog_knife('integer':1, 'string':S, 'string':T) :- + brachylog_knife('integer':1, S, T). +brachylog_knife('integer':1, 'integer':I, 'integer':0) :- + I in -9..9. +brachylog_knife('integer':1, 'integer':I, 'integer':J) :- + H #\= 0, + H2 #\= 0, + abs(J) #=< abs(I), + abs(I) #=< 10*(abs(J) + 1), + integer_value('integer':Sign:[H|T], I), + integer_value('integer':Sign:[H2|T2], J), + brachylog_knife('integer':1, [H|T], [H2|T2]). +brachylog_knife('integer':I, Input, Output) :- + I #> 1, + brachylog_meta_iterate(ignore, 'integer':I, brachylog_knife, 'integer':1, Input, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LENGTH +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_length_reversed(S, I, O) :- + brachylog_length(S, O, I). +brachylog_length('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_length('integer':I, Arg, Output). +brachylog_length('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_length('integer':I, Arg, Output). +brachylog_length('integer':I, Input, Input) :- + I #>= 0, + brachylog_length('default', Input, 'integer':I). +brachylog_length('default', [], 'integer':0). +brachylog_length('default', [H|T], 'integer':Length) :- + length([H|T], Length). +brachylog_length('default', 'string':S, 'integer':Length) :- + length(S, Length). +brachylog_length('default', 'integer':0, 'integer':1). +brachylog_length('default', 'integer':I, 'integer':Length) :- + nonvar(Length), + ( Length = 1 -> + I in 1..9 + ; H #\= 0, + abs(I) #< 10^Length, + integer_value('integer':_:[H|T], I), + length([H|T], Length) + ). +brachylog_length('default', 'integer':I, 'integer':Length) :- + var(Length), + H #\= 0, + Length #>= 0, + integer_value('integer':_:[H|T], I), + length([H|T], Length). +brachylog_length('default', 'float':F, 'integer':Length) :- + nonvar(F), + length(L, Length), + catch(number_codes(F, L), E, (print_message(error, E), false)). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ORDER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_order_reversed(S, I, O) :- + brachylog_order(S, O, I). +brachylog_order('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_order('integer':I, Arg, Output). +brachylog_order('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_order('integer':I, Arg, Output). +brachylog_order('default', Input, Output) :- + brachylog_order('integer':0, Input, Output). +brachylog_order('integer':0, 'string':S, 'string':T) :- + ( nonvar(S), + msort(S, T) + ; var(S), + msort(T, T), + brachylog_permute('default', 'string':T, 'string':S) + ). +brachylog_order('integer':0, 'integer':I, 'integer':J) :- + brachylog_label('default', 'integer':I, _), + number_codes(I, C), + msort(C, D), + number_codes(J, D). +brachylog_order('integer':0, [], []). +brachylog_order('integer':0, [H|T], [H2|T2]) :- + ( nonvar(T), + brachylog_order_mixed_sort_([H|T], [H2|T2]) + ; var(T), + brachylog_order_mixed_sort_([H2|T2], [H2|T2]), + brachylog_permute('default', [H2|T2], [H|T]) + ). +brachylog_order('integer':1, Input, Output) :- + brachylog_order('integer':0, Input, ROutput), + brachylog_reverse('default', ROutput, Output). + +% keysort sorts by the first element of a - pair, disregarding but preserving the second +brachylog_order_type_pair_(List, PairsList-list) :- + maplist(brachylog_order_type_pair_, List, PairsList). +brachylog_order_type_pair_(Type:Value, Value-Type). +brachylog_order_mixed_sort_(List, Sorted) :- + maplist(brachylog_order_type_pair_, List, IPairs), + keysort(IPairs, OPairs), % keysort, like msort, doesn't remove duplicates + maplist(brachylog_order_type_pair_, Sorted, OPairs). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PERMUTE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_permute_reversed(S, I, O) :- + brachylog_permute(S, O, I). +brachylog_permute('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_permute('integer':I, Arg, Output). +brachylog_permute('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_permute('integer':I, Arg, Output). +brachylog_permute('default', Input, Output) :- + brachylog_permute('integer':0, Input, Output). +brachylog_permute('integer':0, 'string':S, 'string':Permutation) :- + permutation(S, Permutation). +brachylog_permute('integer':0, List, Permutation) :- + is_brachylog_list(List), + is_brachylog_list(Permutation), + permutation(List, Permutation). +brachylog_permute('integer':0, 'integer':0, 'integer':0). +brachylog_permute('integer':0, 'integer':I, 'integer':J) :- + H #\= 0, + J #\= 0, + integer_value('integer':Sign:[H|L], I), + permutation([H|L], M), + integer_value('integer':Sign:M, J). +brachylog_permute('integer':0, 'float':F, 'float':G) :- + Sign is abs(F)/F, + AF is abs(F), + number_chars(AF, C), + permutation(C, D), + \+ ( D = ['.'|_] ; reverse(D, ['.'|_])), + number_chars(AG, D), + G is Sign*AG. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SUBSTRING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_substring_reversed(S, I, O) :- + brachylog_substring(S, O, I). +brachylog_substring('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_substring('integer':I, Arg, Output). +brachylog_substring('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_substring('integer':I, Arg, Output). +brachylog_substring('default', 'integer':0, 'integer':0). +brachylog_substring('default', 'integer':I, 'integer':J) :- + H #\= 0, + integer_value('integer':Sign:[H|L], I), + brachylog_substring_recur([H|L], [H2|L2]), + integer_value('integer':Sign:[H2|L2], J). +brachylog_substring('default', 'string':[], 'string':[]). +brachylog_substring('default', 'string':[H|T], 'string':[H2|T2]) :- + brachylog_substring_recur([H|T], [H2|T2]). +brachylog_substring('default', [], []). +brachylog_substring('default', [H|T], [H2|T2]) :- + brachylog_substring_recur([H|T], [H2|T2]). +brachylog_substring('integer':I, Input, Output) :- + brachylog_length('default', Output, 'integer':I), + brachylog_substring('default', Input, Output). + +brachylog_substring_recur([], []). +brachylog_substring_recur([H|T], [H|T2]) :- + brachylog_substring_recur_(T, T2). +brachylog_substring_recur([_|T], T2) :- + brachylog_substring_recur(T, T2). + +brachylog_substring_recur_([], []). +brachylog_substring_recur_([H|T], [H|T2]) :- + brachylog_substring_recur_(T, T2). +brachylog_substring_recur_([_|_], []). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TAIL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_tail_reversed(S, I, O) :- + brachylog_tail(S, O, I). +brachylog_tail('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_tail('integer':I, Arg, Output). +brachylog_tail('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_tail('integer':I, Arg, Output). +brachylog_tail('integer':0, _, []). +brachylog_tail('default', 'string':L, 'string':[H]) :- + reverse(L, [H|_]). +brachylog_tail('default', 'integer':0, 'integer':0). +brachylog_tail('default', 'integer':I, 'integer':Z) :- + J #\= 0, + integer_value('integer':_:[J|T], I), + reverse([J|T], [Z|_]). +brachylog_tail('default', 'float':F, 'integer':I) :- + number_codes(F, L), + reverse(L, R), + brachylog_tail_float(R, 'integer':I). +brachylog_tail('default', L, H) :- + is_brachylog_list(L), + reverse(L, [H|_]). +brachylog_tail('integer':I, Input, Output) :- + I #> 0, + brachylog_length('default', Output, 'integer':I), + once(brachylog_concatenate('default', [_,Output], Input)). + +brachylog_tail_float([H|T], 'integer':I) :- + ( ( H = 48 + ; H = 46 + ) -> + ( T = [], + I = 0 + ; T \= [], + brachylog_tail_float(T, 'integer':I) + ) + ; H \= 48, + H \= 46, + number_codes(I, [H]) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_WRITE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_write_reversed(S, I, O) :- + brachylog_write(S, O, I). +brachylog_write('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_write('integer':I, Arg, Output). +brachylog_write('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_write('integer':I, Arg, Output). +brachylog_write('default', Input, Output) :- + brachylog_write('integer':0, Input, Output). +brachylog_write('integer':Sub, I, O) :- + S #= Sub mod 4, + brachylog_write_('integer':S, I, O, T), + ( Sub #< 4, % imperative write + write(T) + ; Sub #>= 4, + b_getval('declw', DOld), % Declarative write + append(DOld, [T], DNew), + b_setval('declw', DNew) + ). + +brachylog_write_('integer':1, [List,'string':F], _, T) :- + is_brachylog_list(List), + atomic_list_concat(F, Format), + maplist(brachylog_write_try_label, List), + brachylog_prolog_variable(List, PrologList), + format(string(T), Format, PrologList). % Output formatted text +brachylog_write_('integer':1, Args, _, T) :- + is_brachylog_list(Args), + reverse(Args, ['string':F|R]), + reverse(R, S), + maplist(brachylog_write_try_label, S), + brachylog_prolog_variable(S, PrologS), + atomic_list_concat(F, Format), + format(string(T), Format, PrologS). % Output formatted text +brachylog_write_('integer':0, 'string':S, _, X) :- + nonvar(S), + atomic_list_concat(S, X). +brachylog_write_('integer':0, 'integer':I, _, I) :- + brachylog_label('default', 'integer':I, _). +brachylog_write_('integer':0, 'float':F, _, F) :- + nonvar(F). +brachylog_write_('integer':0, List, _, PrologList) :- + is_brachylog_list(List), + maplist(brachylog_write_try_label, List), + brachylog_prolog_variable(List, PrologList). +brachylog_write_('integer':2, I, I, T) :- + brachylog_write_('integer':0, I, _, T). +brachylog_write_('integer':3, I, I, T) :- + brachylog_write_('integer':1, I, _, T). + +brachylog_write_try_label(X) :- + ( nonvar(X), X = 'float':_ -> true + ; nonvar(X), X = 'string':_ -> true + ; nonvar(X), X = [] -> true + ; nonvar(X), + X = [H|T] -> + maplist(brachylog_write_try_label, [H|T]) + ; X = 'integer':I, + brachylog_label('default', 'integer':I, _) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_XTERMINATE + + TODO: Use sub to know what to remove instead +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_xterminate_reversed(S, I, O) :- + brachylog_xterminate(S, O, I). +brachylog_xterminate('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_xterminate('integer':I, Arg, Output). +brachylog_xterminate('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_xterminate('integer':I, Arg, Output). +brachylog_xterminate('default', Input, Output) :- + brachylog_xterminate('integer':0, Input, Output). +brachylog_xterminate('integer':0, [L,[]], L). +brachylog_xterminate('integer':0, ['string':S,X], 'string':T) :- + \+ is_brachylog_list(X), + brachylog_xterminate_(X, 'string':S, 'string':T). +brachylog_xterminate('integer':0, ['string':S,[H|T]], L3) :- + brachylog_xterminate_(H,'string':S, L2), + brachylog_xterminate('integer':0, [L2,T], L3). +brachylog_xterminate('integer':0, [L,H|T], L3) :- + is_brachylog_list(L), + \+ is_brachylog_list(H), + brachylog_xterminate('integer':0, [L,[H|T]], L3). +brachylog_xterminate('integer':0, [L,[H|T]], L3) :- + is_brachylog_list(L), + delete(L, H, L2), + brachylog_xterminate('integer':0, [L2,T], L3). + +brachylog_xterminate_(X, 'string':S, 'string':T) :- + brachylog_xterminate_single(X, 'string':S, 'string':T). +brachylog_xterminate_(_, [], []). +brachylog_xterminate_(X, [H|T], [H2|T2]) :- + brachylog_xterminate_single(X, H, H2), + brachylog_xterminate_(X, T, T2). + +brachylog_xterminate_single('string':L, 'string':H, 'string':Z) :- + ( append([A,L,B], H), + append(A,B,H2), + brachylog_xterminate_single('string':L, 'string':H2, 'string':Z) + ; \+ append([_,L,_], H), + Z = H + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ZIP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_zip_reversed(S, I, O) :- + brachylog_zip(S, O, I). +brachylog_zip('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_zip('integer':I, Arg, Output). +brachylog_zip('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_zip('integer':I, Arg, Output). +brachylog_zip('default', L,Z) :- + is_brachylog_list(L), + maplist(brachylog_length('default'), L, Lengths), + brachylog_order('default', Lengths, OrderedLengths), + reverse(OrderedLengths, ['integer':MaxLength|_]), + maplist(brachylog_zip_listify_integer, L, L2), + brachylog_zip_(L2, MaxLength, Z). +brachylog_zip('integer':0, L, Z) :- + is_brachylog_list(L), + maplist(brachylog_length('default'), L, Lengths), + brachylog_order('default', Lengths, ['integer':MinLength|_]), + maplist(brachylog_zip_listify_integer, L, L2), + brachylog_zip_(L2, MinLength, Z). +brachylog_zip('integer':1, L, Z) :- + is_brachylog_list(L), + maplist(brachylog_zip_listify_integer, L, L2), + brachylog_zip_no_cycling(L2, Z). +brachylog_zip('integer':2, L, Z) :- + maplist(brachylog_length_reversed('default', _), L), % fails if the lengths aren't all the same + brachylog_zip('default', L, Z). + +brachylog_zip_(_, 0, []). +brachylog_zip_(L, I, [Heads|Z]) :- + I #> 0, + maplist(brachylog_head('default'), L, Heads), + maplist(brachylog_circular_permute_counterclockwise('default'), L, Tails), + J #= I - 1, + brachylog_zip_(Tails, J, Z). + +brachylog_zip_no_cycling([H|T], Z) :- + brachylog_meta_select(ignore, 'default', brachylog_head, 'default', [H|T], Heads), + ( Heads = [] -> + Z = [] + ; Z = [Heads|Z2], + brachylog_meta_select(ignore, 'default', brachylog_behead, 'default', [H|T], Tails), + brachylog_zip_no_cycling(Tails, Z2) + ). + +brachylog_zip_listify_integer(L, L) :- + L \= 'integer':_. +brachylog_zip_listify_integer('integer':I, L) :- + brachylog_elements('default', 'integer':I, L). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TO_CODES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_to_codes_reversed(S, I, O) :- + brachylog_to_codes(S, O, I). +brachylog_to_codes('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_to_codes('integer':I, Arg, Output). +brachylog_to_codes('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_to_codes('integer':I, Arg, Output). +brachylog_to_codes('default', 'string':[], []). +brachylog_to_codes('default', 'string':[H|T], ['integer':I|T2]) :- + ( var(T) -> + length(T2,Length), + length(T,Length) + ; length(T,Length), + length(T2,Length) + ), + maplist(prepend_integer, L, ['integer':I|T2]), + maplist(single_atom_code, [H|T],L). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_BLOCKS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_blocks_reversed(S, I, O) :- + brachylog_blocks(S, O, I). +brachylog_blocks('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_blocks('integer':I, Arg, Output). +brachylog_blocks('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_blocks('integer':I, Arg, Output). +brachylog_blocks('default', [], []). +brachylog_blocks('default', [H|T], Blocks) :- + brachylog_blocks('default', [H|T], H, Blocks). +brachylog_blocks('default', 'string':[H|T], StringBlocks) :- + maplist(prepend_string, Blocks, StringBlocks), + brachylog_blocks('default', [H|T], H, Blocks), + !. + +brachylog_blocks('default', [], _, [[]]). +brachylog_blocks('default', [H|T], H, [[H|T2]|T3]) :- + brachylog_blocks('default', T, H, [T2|T3]). +brachylog_blocks('default', [H|T], I, [[],[H|T2]|T3]) :- + dif(H, I), + brachylog_blocks('default', T, H, [T2|T3]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DICHOTOMIZE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_dichotomize_reversed(S, I, O) :- + brachylog_dichotomize(S, O, I). +brachylog_dichotomize('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_dichotomize('integer':I, Arg, Output). +brachylog_dichotomize('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_dichotomize('integer':I, Arg, Output). +brachylog_dichotomize('default', Input, Output) :- + brachylog_dichotomize('integer':2, Input, Output). +brachylog_dichotomize('integer':I, Input, Output) :- + brachylog_label('default', 'integer':I, _), + length(Output, I), + brachylog_dichotomize(Input, Output). +brachylog_dichotomize('string':L, L2) :- + maplist(prepend_string,M, L2), + brachylog_dichotomize(L, M). +brachylog_dichotomize('integer':0, L2) :- + length(L2, Length), + length(M, Length), + brachylog_dichotomize([0], M), + maplist(maplist(prepend_integer), M, L2). +brachylog_dichotomize('integer':I, L2) :- + H #\= 0, + integer_value('integer':_:[H|T], I), + length(L2, Length), + length(M, Length), + brachylog_dichotomize([H|T], M), + maplist(maplist(prepend_integer), M, L2). +brachylog_dichotomize(L, L2) :- + is_brachylog_list(L), + maplist(is_brachylog_list, L2), + Length #= LengthL//LengthL2, + length(L2, LengthL2), + length(L, LengthL), + reverse(L2, [_|T]), + maplist(length_(Length), T), + append(L2, L), + !. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ELEMENTS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_elements_reversed(S, I, O) :- + brachylog_elements(S, O, I). +brachylog_elements('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_elements('integer':I, Arg, Output). +brachylog_elements('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_elements('integer':I, Arg, Output). +brachylog_elements('default', [], []). +brachylog_elements('default', [H|T], L) :- + maplist(brachylog_elements('default'), [H|T], L). +brachylog_elements('default', 'string':S, L) :- + brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'string':S, L). +brachylog_elements('default', 'integer':I, L) :- + brachylog_meta_find(ignore, 'default', brachylog_in, 'default', 'integer':I, L). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TO_NUMBER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_to_number_reversed(S, I, O) :- + brachylog_to_number(S, O, I). +brachylog_to_number('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_to_number('integer':I, Arg, Output). +brachylog_to_number('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_to_number('integer':I, Arg, Output). +brachylog_to_number('default', 'string':S, Type:N) :- + atomic_list_concat(S, A), + atom_number(A,N), + ( member('.', S) -> + Type = 'float' + ; Type = 'integer' + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LOWERCASE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_lowercase_reversed(S, I, O) :- + brachylog_lowercase(S, O, I). +brachylog_lowercase('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_lowercase('integer':I, Arg, Output). +brachylog_lowercase('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_lowercase('integer':I, Arg, Output). +brachylog_lowercase('default', 'string':Ls0, 'string':Ls) :- + maplist(downcase_atom, Ls0, Ls). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SPLIT_LINES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_split_lines_reversed(S, I, O) :- + brachylog_split_lines(S, O, I). +brachylog_split_lines('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_split_lines('integer':I, Arg, Output). +brachylog_split_lines('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_split_lines('integer':I, Arg, Output). +brachylog_split_lines('default', 'string':[], ['string':[]]). +brachylog_split_lines('default', 'string':['\n'|T], ['string':[]|T3]) :- + brachylog_split_lines('default', 'string':T, T3). +brachylog_split_lines('default', 'string':['\r','\r\n'|T], ['string':[]|T3]) :- + brachylog_split_lines('default', 'string':T, T3). +brachylog_split_lines('default', 'string':[H|T], ['string':[H|T2]|T3]) :- + dif(H, '\n'), + dif(H, '\r\n'), + brachylog_split_lines('default', 'string':T, ['string':T2|T3]). +brachylog_split_lines('integer':1, 'string':[], ['string':[]]). +brachylog_split_lines('integer':1, 'string':[' '|T], ['string':[]|T3]) :- + brachylog_split_lines('integer':1, 'string':T, T3). +brachylog_split_lines('integer':1, 'string':[H|T], ['string':[H|T2]|T3]) :- + dif(H, ' '), + brachylog_split_lines('integer':1, 'string':T, ['string':T2|T3]). +brachylog_split_lines('integer':2, 'string':[], ['string':[]]). +brachylog_split_lines('integer':2, 'string':[' '|T], ['string':[]|T3]) :- + brachylog_split_lines('integer':2, 'string':T, T3). +brachylog_split_lines('integer':2, 'string':['\n'|T], ['string':[]|T3]) :- + brachylog_split_lines('integer':2, 'string':T, T3). +brachylog_split_lines('integer':2, 'string':['\r','\r\n'|T], ['string':[]|T3]) :- + brachylog_split_lines('integer':2, 'string':T, T3). +brachylog_split_lines('integer':2, 'string':[H|T], ['string':[H|T2]|T3]) :- + dif(H, '\n'), + dif(H, '\r\n'), + dif(H, ' '), + brachylog_split_lines('integer':2, 'string':T, ['string':T2|T3]). +brachylog_split_lines('integer':3, Input, Output) :- + brachylog_split_lines('default', Input, L1), + brachylog_meta_map(ignore, 'default', brachylog_split_lines, 'integer':1, L1, Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_OCCURENCES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_occurences_reversed(S, I, O) :- + brachylog_occurences(S, O, I). +brachylog_occurences('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_occurences('integer':I, Arg, Output). +brachylog_occurences('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_occurences('integer':I, Arg, Output). +brachylog_occurences('default', 'string':[], []). +brachylog_occurences('default', 'string':[H|T], L) :- + brachylog_elements('default', 'string':[H|T], E), + brachylog_occurences('default', E, L). +brachylog_occurences('default', 'integer':0, [['integer':0,'integer':1]]). +brachylog_occurences('default', 'integer':I, L) :- + H #\= 0, + brachylog_elements('default', 'integer':I, ['integer':H|T]), + brachylog_occurences('default', ['integer':H|T], L). +brachylog_occurences('default', [], []). +brachylog_occurences('default', [H|T], [[H,'integer':O]|T2]) :- + brachylog_occurences_(H, [H|T], O, R), + brachylog_occurences('default', R, T2). + +brachylog_occurences_(_, [], 0, []). +brachylog_occurences_(H, [H|T], I, R) :- + I #= J + 1, + brachylog_occurences_(H, T, J, R). +brachylog_occurences_(H, [H2|T], I, [H2|R]) :- + dif(H, H2), + brachylog_occurences_(H, T, I, R). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANDOM_ELEMENT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_random_element_reversed(S, I, O) :- + brachylog_random_element(S, O, I). +brachylog_random_element('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_random_element('integer':I, Arg, Output). +brachylog_random_element('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_random_element('integer':I, Arg, Output). +brachylog_random_element('default', [], []). +brachylog_random_element('default', [H|T], R) :- + length([H|T], L), + M #= L - 1, + random_between(0, M, I), + nth0(I, [H|T], R). +brachylog_random_element('default', 'string':S, 'string':[R]) :- + brachylog_random_element('default', S, R). +brachylog_random_element('default', 'integer':0, 'integer':0). +brachylog_random_element('default', 'integer':I, 'integer':R) :- + H #\= 0, + integer_value('integer':_:[H|T], I), + brachylog_random_element('default', [H|T], R). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SHUFFLE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_shuffle_reversed(S, I, O) :- + brachylog_shuffle(S, O, I). +brachylog_shuffle('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_shuffle('integer':I, Arg, Output). +brachylog_shuffle('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_shuffle('integer':I, Arg, Output). +brachylog_shuffle('default', [], []). +brachylog_shuffle('default', [H|T], [H2|T2]) :- + random_permutation([H|T], [H2|T2]). +brachylog_shuffle('default', 'string':S, 'string':T) :- + brachylog_shuffle('default', S, T). +brachylog_shuffle('default', 'integer':I, 'integer':J) :- + H #\= 0, + integer_value('integer':Sign:[H|T], I), + ( H2 #\= 0, + brachylog_shuffle('default', [H|T], [H2|T2]) -> + integer_value('integer':Sign:[H2|T2], J) + ; brachylog_shuffle('default', 'integer':I, 'integer':J) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_UPPERCASE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_uppercase_reversed(S, I, O) :- + brachylog_uppercase(S, O, I). +brachylog_uppercase('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_uppercase('integer':I, Arg, Output). +brachylog_uppercase('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_uppercase('integer':I, Arg, Output). +brachylog_uppercase('default', 'string':Ls0, 'string':Ls) :- + maplist(upcase_atom, Ls0, Ls). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_WRITELN +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_writeln_reversed(S, I, O) :- + brachylog_writeln(S, O, I). +brachylog_writeln('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_writeln('integer':I, Arg, Output). +brachylog_writeln('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_writeln('integer':I, Arg, Output). +brachylog_writeln('default', I, O) :- + brachylog_writeln('integer':0, I, O). +brachylog_writeln('integer':Sub, I, O) :- + brachylog_write('integer':Sub, I, O), + ( Sub #> 3, % declarative write + brachylog_write('integer':4, 'string':['\n'], _) + ; Sub #< 4, % imperative write + brachylog_write('default', 'string':['\n'], _) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ABSOLUTE_VALUE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_absolute_value_reversed(S, I, O) :- + brachylog_absolute_value(S, O, I). +brachylog_absolute_value('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_absolute_value('integer':I, Arg, Output). +brachylog_absolute_value('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_absolute_value('integer':I, Arg, Output). +brachylog_absolute_value('default', 'integer':I, 'integer':J) :- + J #= abs(I). +brachylog_absolute_value('default', 'float':I, 'float':J) :- + nonvar(I), + J is abs(I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_BASE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_base_reversed(S, I, O) :- + brachylog_base(S, O, I). +brachylog_base('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_base('integer':I, Arg, Output). +brachylog_base('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_base('integer':I, Arg, Output). +brachylog_base('default', Input, Output) :- + brachylog_base('integer':2, Input, Output). +brachylog_base('integer':1, 'integer':I, Output) :- + brachylog_label('default', 'integer':I, _), + length(Output, I), + ( Output = ['integer':1|_] -> + brachylog_equal('default', Output, _) + ; true + ). +brachylog_base('integer':B, 'integer':I, L) :- + B #> 1, + %brachylog_label('default', ['integer':I, 'integer':B], _), + ( I #>= 0 + ; I #< 0 + ), + J #= abs(I), + n_base_digits(J, B, L). + +% Credits to @repeat +% See: http://stackoverflow.com/a/33543199/2554145 +n_base_digits(Expr, Base, Ds) :- + Base #> 1, + Ds = [_|_], + N #= Expr, + N #>= 0, + n_base_ref_acc_digits(N, Base, Ds, [], Ds). + +n_base_ref_acc_digits(N, Base, Ref, Ds0, Ds) :- + zcompare(Order, N, Base), + order_n_base_ref_acc_digits(Order, N, Base, Ref, Ds0, Ds). + +order_n_base_ref_acc_digits(<, N, _, [_], Ds0, ['integer':N|Ds0]). +order_n_base_ref_acc_digits(=, _, _, [_,_], Ds0, ['integer':1,'integer':0|Ds0]). +order_n_base_ref_acc_digits(>, N, Base, [_|Rs], Ds0, Ds) :- + N0 #= N // Base, + N1 #= N mod Base, + n_base_ref_acc_digits(N0, Base, Rs, ['integer':N1|Ds0], Ds). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_COERCE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_coerce_reversed(S, I, O) :- + brachylog_coerce(S, O, I). +brachylog_coerce('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_coerce('integer':I, Arg, Output). +brachylog_coerce('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_coerce('integer':I, Arg, Output). +brachylog_coerce('default', [], []). +brachylog_coerce('default', [H|T], [H|T]). +brachylog_coerce('integer':1, 'integer':I, 'integer':I). +brachylog_coerce('integer':2, 'string':S, 'string':S). + + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PRIME_DECOMPOSITION + + Credits to RosettaCode +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_prime_decomposition_reversed(S, I, O) :- + brachylog_prime_decomposition(S, O, I). +brachylog_prime_decomposition('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_prime_decomposition('integer':I, Arg, Output). +brachylog_prime_decomposition('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_prime_decomposition('integer':I, Arg, Output). +brachylog_prime_decomposition('default', 'integer':N, Z) :- + N #> 0, + brachylog_label('default', 'integer':N, _), + ceiled_square_root(N, SN), + brachylog_prime_decomposition_1(N, SN, 2, [], L), + brachylog_prime_decomposition_append_integer(L, Z). + +brachylog_prime_decomposition_1(1, _, _, L, L) :- !. +brachylog_prime_decomposition_1(N, SN, D, L, LF) :- + ( 0 #= N mod D -> + Q #= N // D, + ceiled_square_root(Q, SQ), + brachylog_prime_decomposition_1(Q, SQ, D, [D|L], LF) + ; D1 #= D + 1, + ( D1 #> SN -> + LF = [N|L] + ; brachylog_prime_decomposition_2(N, SN, D1, L, LF) + ) + ). + +brachylog_prime_decomposition_2(1, _, _, L, L) :- !. +brachylog_prime_decomposition_2(N, SN, D, L, LF) :- + ( 0 #= N mod D -> + Q #= N // D, + ceiled_square_root(Q, SQ), + brachylog_prime_decomposition_2(Q, SQ, D, [D|L], LF); + D1 #= D + 2, + ( D1 #> SN -> + LF = [N|L] + ; brachylog_prime_decomposition_2(N, SN, D1, L, LF) + ) + ). + +brachylog_prime_decomposition_append_integer([], []). +brachylog_prime_decomposition_append_integer([H|T], ['integer':H|T2]) :- + brachylog_prime_decomposition_append_integer(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FACTORIAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_factorial_reversed(S, I, O) :- + brachylog_factorial(S, O, I). +brachylog_factorial('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_factorial('integer':I, Arg, Output). +brachylog_factorial('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_factorial('integer':I, Arg, Output). +brachylog_factorial('default', 'integer':N, 'integer':F) :- + brachylog_factorial_(N, 0, 1, F). + +brachylog_factorial_(N, I, N0, F) :- + F #> 0, + N #>= 0, + I #>= 0, + I #=< N, + N0 #> 0, + N0 #=< F, + if_(I #> 2, + ( F #> N, + if_(===(N, I, N0, F, T1), + if_(T1 = true, + N0 = F, + N = I + ), + ( J #= I + 1, + N1 #= N0*J, + predicates:brachylog_factorial_(N, J, N1, F) + ) + ) + ), + if_(N = I, + N0 = F, + ( J #= I + 1, + N1 #= N0*J, + predicates:brachylog_factorial_(N, J, N1, F) + ) + ) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GROUPS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_groups_reversed(S, I, O) :- + brachylog_groups(S, O, I). +brachylog_groups('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_groups('integer':I, Arg, Output). +brachylog_groups('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_groups('integer':I, Arg, Output). +brachylog_groups('default', Input, Output) :- + I in 1..sup, + brachylog_groups('integer':I, Input, Output). +brachylog_groups('integer':I, 'string':Input, Output) :- + brachylog_groups('integer':I, Input, S), + maplist(prepend_string, S, Output). +brachylog_groups('integer':I, 'integer':Input, Output) :- + H #\= 0, + integer_value('integer':_:[H|T], Input), + brachylog_groups('integer':I, [H|T], S), + maplist(brachylog_groups_ints, S, Output). +brachylog_groups('integer':I, Input, Output) :- + maplist(is_brachylog_list, [Input, Output]), + brachylog_groups(I, [], Input, Output). + +brachylog_groups(_, [H|T], [], [RL]) :- + reverse([H|T], RL). +brachylog_groups(I, L, Input, [RL|T2]) :- + length(L, I), + reverse(L, RL), + brachylog_groups(I, [], Input, T2). +brachylog_groups(I, L, [H|T], Output) :- + J #< I, + J #>= 0, + length(L, J), + brachylog_groups(I, [H|L], T, Output). + +brachylog_groups_ints(I, 'integer':O) :- + integer_value('integer':'positive':I, O). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MATRIX +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_matrix_reversed(S, I, O) :- + brachylog_matrix(S, O, I). +brachylog_matrix('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_matrix('integer':I, Arg, Output). +brachylog_matrix('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_matrix('integer':I, Arg, Output). +brachylog_matrix('default', M, M) :- + L in 0..sup, + brachylog_matrix('integer':L, M, M). +brachylog_matrix('integer':L, M, M) :- + length(M, L), + maplist(length_(L), M). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_NEGATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_negate_reversed(S, I, O) :- + brachylog_negate(S, O, I). +brachylog_negate('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_negate('integer':I, Arg, Output). +brachylog_negate('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_negate('integer':I, Arg, Output). +brachylog_negate('default', 'integer':I, 'integer':J) :- + J #= -I. +brachylog_negate('default', 'float':I, 'float':J) :- + nonvar(I), + J is -I. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PRIME +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_prime_reversed(S, I, O) :- + brachylog_prime(S, O, I). +brachylog_prime('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_prime('integer':I, Arg, Output). +brachylog_prime('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_prime('integer':I, Arg, Output). +brachylog_prime('default', 'integer':N, 'integer':N) :- + clpfd:make_propagator(prime(N), Prop), + clpfd:init_propagator(N, Prop), + clpfd:trigger_once(Prop). + +clpfd:run_propagator(prime(N), MState) :- + ( nonvar(N) -> + clpfd:kill(MState), + check_prime(N) + ; clpfd:fd_get(N, ND, NL, NU, NPs), + clpfd:cis_max(NL, n(2), NNL), + clpfd:update_bounds(N, ND, NPs, NL, NU, NNL, NU) + ). + +:- if(current_predicate(crypto_is_prime/2)). +probably_prime(P) :- crypto_is_prime(P, []). +:- else. +probably_prime(_). +:- endif. + +check_prime(N) :- + ( N = 2 -> + true + ; N #> 2, + probably_prime(N), + ceiled_square_root(N, SN), + check_prime_1(N, SN, 2, [], [_]) + ). + +check_prime_1(1, _, _, L, L) :- !. +check_prime_1(N, SN, D, L, LF) :- + ( 0 #= N mod D -> + false + ; D1 #= D+1, + ( D1 #> SN -> + LF = [N|L] + ; check_prime_2(N, SN, D1, L, LF) + ) + ). + +check_prime_2(1, _, _, L, L) :- !. +check_prime_2(N, SN, D, L, LF) :- + ( 0 #= N mod D -> false + ; D1 #= D+2, + ( D1 #> SN -> + LF = [N|L] + ; check_prime_2(N, SN, D1, L, LF) + ) +). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANDOM_NUMBER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_random_number_reversed(S, I, O) :- + brachylog_random_number(S, O, I). +brachylog_random_number('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_random_number('integer':I, Arg, Output). +brachylog_random_number('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_random_number('integer':I, Arg, Output). +brachylog_random_number('default', 'integer':I, 'integer':R) :- + brachylog_random_number(['integer':0,'integer':I], 'integer':R). +brachylog_random_number('default', 'float':I, 'float':R) :- + brachylog_random_number(['float':0.0,'float':I], 'float':R). +brachylog_random_number('integer':1, _, 'float':R) :- + brachylog_random_number(['float':0, 'float':1], 'float':R). +brachylog_random_number('integer':2, [A,B], R) :- + brachylog_random_number([A,B], R). + +brachylog_random_number(['integer':I,'integer':J], 'integer':R) :- + brachylog_label('default', ['integer':I,'integer':J], _), + ( I #=< J -> + random_between(I, J, R) + ; random_between(J, I, R) + ). +brachylog_random_number(['float':I,'float':J], 'float':R) :- + random(K), + ( I =< J -> + R is I + K*(J - I) + ; R is J + K*(I - J) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SIGN +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_sign_reversed(S, I, O) :- + brachylog_sign(S, O, I). +brachylog_sign('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_sign('integer':I, Arg, Output). +brachylog_sign('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_sign('integer':I, Arg, Output). +brachylog_sign('default', 'integer':I, 'integer':S) :- + ( I = 0, + S = 0 + ; I #\= 0, + S in -1\/1, + S #= abs(I) // I + ). +brachylog_sign('default', 'float':F, 'integer':S) :- + nonvar(F), + ( F =:= 0.0 -> S = 0 + ; F > 0.0 -> S = 1 + ; F < 0.0 -> S = -1 + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TO_STRING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_to_string_reversed(S, I, O) :- + brachylog_to_string(S, O, I). +brachylog_to_string('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_to_string('integer':I, Arg, Output). +brachylog_to_string('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_to_string('integer':I, Arg, Output). +brachylog_to_string('default', 'integer':I, 'string':S) :- + brachylog_label('default', 'integer':I, 'integer':I), + atom_number(A, I), + atom_chars(A, S). +brachylog_to_string('default', 'float':F, 'string':S) :- + atom_number(A, F), + atom_chars(A, S). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CARTESIAN_PRODUCT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_cartesian_product_reversed(S, I, O) :- + brachylog_cartesian_product(S, O, I). +brachylog_cartesian_product('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_cartesian_product('integer':I, Arg, Output). +brachylog_cartesian_product('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_cartesian_product('integer':I, Arg, Output). +brachylog_cartesian_product('default', Input, Output) :- + findall(L, brachylog_meta_map('ignore', 'default', brachylog_in, 'default', Input, L), Output). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LABEL + + Credits to Markus Triska + See: http://codereview.stackexchange.com/questions/129924/clpfd-labeling-on-possibly-infinite-domains/129945#129945 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_label_reversed(S, I, O) :- + brachylog_label(S, O, I). +brachylog_label('first', ['integer':I|Input], Output) :- + ( Input = [Arg] -> true + ; Input = Arg + ), + brachylog_label('integer':I, Arg, Output). +brachylog_label('last', Input, Output) :- + reverse(Input, ['integer':I|T]), + ( T = [Arg] -> true + ; reverse(T, Arg) + ), + brachylog_label('integer':I, Arg, Output). +brachylog_label('default', Input, Output) :- + brachylog_label('integer':0, Input, Output). +brachylog_label('integer':0, 'integer':Z, 'integer':Z) :- + unsafe_indomain(Z). +brachylog_label('integer':0, Z, Z) :- + is_brachylog_list(Z), + maplist(brachylog_label('integer':0), Z, _). +brachylog_label('integer':1, 'integer':Z, 'integer':Z) :- + get_time(T), + T2 is ceil(1000000 * T), + labeling([random_value(T2)], [Z]). +brachylog_label('integer':1, Z, Z) :- + is_brachylog_list(Z), + get_time(T), + T2 is ceil(1000000 * T), + labeling([random_value(T2)], Z). + +unsafe_indomain(X) :- + fd_inf(X, Inf0), + fd_sup(X, Sup0), + maplist(limit_pure, [Inf0,Sup0], [Inf,Sup]), + unsafe_indomain_(Inf, Sup, X). + +limit_pure(inf, inf) :- !. +limit_pure(sup, sup) :- !. +limit_pure(N, n(N)) :- !. + +unsafe_indomain_(inf, Sup, X) :- + infinite_down(Sup, X). +unsafe_indomain_(n(Low), Sup, X) :- + unsafe_up_(Sup, Low, X). + +infinite_down(sup, X) :- + ( X = 0 + ; abs(X) #= abs(N), + positive_integer(N), + ( X #= N ; X #= -N ) + ). +infinite_down(n(Up), X ) :- + ( between(0, Up, X) + ; abs(X) #= abs(N), + positive_integer(N), + X #= -N + ). + +unsafe_up_(sup, Low, X) :- + ( between(Low, 0, X) + ; positive_integer(X) + ). +unsafe_up_(n(Up), Low, X) :- between(Low, Up, X). + +% See: http://stackoverflow.com/a/39259871/2554145 +positive_integer(I) :- + I #> 0, + ( var(I) -> + fd_inf(I, Inf), + ( I #= Inf + ; I #\= Inf, + positive_integer(I) + ) + ; true + ). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/symbols.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/symbols.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,215 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(symbols, [token_predicate/2, + token_variable/2, + token_metapredicate/2 + ]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKEN_PREDICATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +token_predicate('≤', 'brachylog_lessequal'). +token_predicate('≥', 'brachylog_greaterequal'). +token_predicate('∈', 'brachylog_contains'). +token_predicate('∋', 'brachylog_in'). +token_predicate('⊆', 'brachylog_superset'). +token_predicate('⊇', 'brachylog_subset'). +token_predicate('↔', 'brachylog_reverse'). +token_predicate('↰', 'brachylog_call_predicate'). +token_predicate('↺', 'brachylog_circular_permute_counterclockwise'). +token_predicate('↻', 'brachylog_circular_permute_clockwise'). +token_predicate('√', 'brachylog_root'). +token_predicate('⌉', 'brachylog_ceil'). +token_predicate('⌋', 'brachylog_floor'). +token_predicate('⟦', 'brachylog_range_ascending'). +token_predicate('⟧', 'brachylog_range_descending'). +token_predicate('ℕ', 'brachylog_natural_integer'). +token_predicate('ℤ', 'brachylog_integer'). +token_predicate('ℝ', 'brachylog_float'). +token_predicate('≠', 'brachylog_different'). +token_predicate('≡', 'brachylog_identity'). +token_predicate('÷', 'brachylog_integer_division'). +token_predicate('×', 'brachylog_multiply'). +token_predicate('%', 'brachylog_modulo'). +token_predicate('*', 'brachylog_exp'). +token_predicate('+', 'brachylog_plus'). +token_predicate('-', 'brachylog_minus'). +token_predicate('/', 'brachylog_divide'). +token_predicate('<', 'brachylog_less'). +token_predicate('=', 'brachylog_equal'). +token_predicate('>', 'brachylog_greater'). +token_predicate('\\', 'brachylog_transpose'). +token_predicate('^', 'brachylog_power'). +token_predicate('≜', 'brachylog_label'). + +token_predicate('a', 'brachylog_adfix'). +token_predicate('b', 'brachylog_behead'). +token_predicate('c', 'brachylog_concatenate'). +token_predicate('d', 'brachylog_duplicates'). +token_predicate('e', ''). +token_predicate('f', 'brachylog_factors'). +token_predicate('g', 'brachylog_group'). +token_predicate('h', 'brachylog_head'). +token_predicate('i', 'brachylog_index'). +token_predicate('j', 'brachylog_juxtapose'). +token_predicate('k', 'brachylog_knife'). +token_predicate('l', 'brachylog_length'). +token_predicate('m', ''). +token_predicate('n', ''). +token_predicate('o', 'brachylog_order'). +token_predicate('p', 'brachylog_permute'). +token_predicate('q', ''). +token_predicate('r', ''). +token_predicate('s', 'brachylog_substring'). +token_predicate('t', 'brachylog_tail'). +token_predicate('u', ''). +token_predicate('v', ''). +token_predicate('w', 'brachylog_write'). +token_predicate('x', 'brachylog_xterminate'). +token_predicate('y', ''). +token_predicate('z', 'brachylog_zip'). + +token_predicate('ạ', 'brachylog_to_codes'). +token_predicate('ḅ', 'brachylog_blocks'). +token_predicate('ḍ', 'brachylog_dichotomize'). +token_predicate('ẹ', 'brachylog_elements'). +token_predicate('ḥ', ''). +token_predicate('ị', 'brachylog_to_number'). +token_predicate('ḳ', ''). +token_predicate('ḷ', 'brachylog_lowercase'). +token_predicate('ṃ', ''). +token_predicate('ṇ', 'brachylog_split_lines'). +token_predicate('ọ', 'brachylog_occurences'). +token_predicate('ṛ', 'brachylog_random_element'). +token_predicate('ṣ', 'brachylog_shuffle'). +token_predicate('ṭ', ''). +token_predicate('ụ', 'brachylog_uppercase'). +token_predicate('ṿ', ''). +token_predicate('ẉ', 'brachylog_writeln'). +token_predicate('ỵ', ''). +token_predicate('ẓ', ''). + +token_predicate('ȧ', 'brachylog_absolute_value'). +token_predicate('ḃ', 'brachylog_base'). +token_predicate('ċ', 'brachylog_coerce'). +token_predicate('ḋ', 'brachylog_prime_decomposition'). +token_predicate('ė', ''). +token_predicate('ḟ', 'brachylog_factorial'). +token_predicate('ġ', 'brachylog_groups'). +token_predicate('ḣ', ''). +token_predicate('ṁ', 'brachylog_matrix'). +token_predicate('ṅ', 'brachylog_negate'). +token_predicate('ȯ', ''). +token_predicate('ṗ', 'brachylog_prime'). +token_predicate('ṙ', 'brachylog_random_number'). +token_predicate('ṡ', 'brachylog_sign'). +token_predicate('ṫ', 'brachylog_to_string'). +token_predicate('ẇ', ''). +token_predicate('ẋ', 'brachylog_cartesian_product'). +token_predicate('ẏ', ''). +token_predicate('ż', ''). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKEN_VARIABLE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +token_variable('Ạ', '\'string\':[a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z]'). +token_variable('Ḅ', '\'string\':[b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,y,z]'). +%token_variable('', ''). +token_variable('Ḍ', '\'string\':[b,c,d,f,g,h,j,k,l,m,n,p,q,r,s,t,v,w,x,z]'). +token_variable('Ẹ', '\'string\':[]'). +%token_variable('', ''). +%token_variable('', ''). +token_variable('Ḥ', '\'string\':[\'H\',e,l,l,o,\',\',\' \',\'W\',o,r,l,d,\'!\']'). +token_variable('Ị', '\'string\':[\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\']'). +%token_variable('', ''). +token_variable('Ḳ', ''). +token_variable('Ḷ', '\'string\':[\'\n\']'). +token_variable('Ṃ', ''). +token_variable('Ṇ', '\'string\':[\'A\',\'B\',\'C\',\'D\',\'E\',\'F\',\'G\',\'H\',\'I\',\'J\',\'K\',\'L\',\'M\',\'N\',\'O\',\'P\',\'Q\',\'R\',\'S\',\'T\',\'U\',\'V\',\'W\',\'X\',\'Y\',\'Z\',a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,0,1,2,3,4,5,6,7,8,9]'). +token_variable('Ọ', ''). +%token_variable('', ''). +%token_variable('', ''). +token_variable('Ṛ', ''). +token_variable('Ṣ', '\'string\':[\' \']'). +token_variable('Ṭ', '\'string\':[\' \',\'!\',\'"\',\'#\',\'$\',\'%\',\'&\',\'\\\'\',\'(\',\')\',\'*\',\'+\',\',\',\'-\',\'.\',\'/\',\'0\',\'1\',\'2\',\'3\',\'4\',\'5\',\'6\',\'7\',\'8\',\'9\',\':\',\';\',\'<\',\'=\',\'>\',\'?\',\'@\',\'A\',\'B\',\'C\',\'D\',\'E\',\'F\',\'G\',\'H\',\'I\',\'J\',\'K\',\'L\',\'M\',\'N\',\'O\',\'P\',\'Q\',\'R\',\'S\',\'T\',\'U\',\'V\',\'W\',\'X\',\'Y\',\'Z\',\'[\',\'\\\\\',\']\',\'^\',\'_\',\'`\',\'a\',\'b\',\'c\',\'d\',\'e\',\'f\',\'g\',\'h\',\'i\',\'j\',\'k\',\'l\',\'m\',\'n\',\'o\',\'p\',\'q\',\'r\',\'s\',\'t\',\'u\',\'v\',\'w\',\'x\',\'y\',\'z\',\'{\',\'|\',\'}\',\'~\']'). +token_variable('Ụ', ''). +token_variable('Ṿ', '\'string\':[a,e,i,o,u]'). +token_variable('Ẉ', '\'string\':[a,e,i,o,u,y]'). +%token_variable('', ''). +token_variable('Ỵ', ''). +token_variable('Ẓ', '\'string\':[z,y,x,w,v,u,t,s,r,q,p,o,n,m,l,k,j,i,h,g,f,e,d,c,b,a]'). + +token_variable('Ȧ', 'ConstraintA'). +token_variable('Ḃ', 'ConstraintB'). +token_variable('Ċ', 'ConstraintC'). +token_variable('Ḋ', 'ConstraintD'). +token_variable('Ė', 'ConstraintE'). +token_variable('Ḟ', 'ConstraintF'). +token_variable('Ġ', 'ConstraintG'). +token_variable('Ḣ', 'ConstraintH'). +token_variable('İ', 'ConstraintI'). +%token_variable('', 'ConstraintJ'). +%token_variable('', 'ConstraintK'). +%token_variable('', 'ConstraintL'). +token_variable('Ṁ', 'ConstraintM'). +token_variable('Ṅ', 'ConstraintN'). +token_variable('Ȯ', 'ConstraintO'). +token_variable('Ṗ', 'ConstraintP'). +%token_variable('', 'ConstraintQ'). +token_variable('Ṙ', 'ConstraintR'). +token_variable('Ṡ', 'ConstraintS'). +token_variable('Ṫ', 'ConstraintT'). +%token_variable('', 'ConstraintU'). +%token_variable('', 'ConstraintV'). +token_variable('Ẇ', 'ConstraintW'). +token_variable('Ẋ', 'ConstraintX'). +token_variable('Ẏ', 'ConstraintY'). +token_variable('Ż', 'ConstraintZ'). + +token_variable('π', '\'float\':3.14159265359'). +token_variable('φ', '\'float\':1.61803398875'). + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKEN_METAPREDICATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +token_metapredicate('ᵃ', 'brachylog_meta_accumulate'). +token_metapredicate('ᵇ', 'brachylog_meta_bagof'). +token_metapredicate('ᶜ', 'brachylog_meta_count'). +token_metapredicate('ᵈ', 'brachylog_meta_declare'). +token_metapredicate('ᵉ', 'brachylog_meta_existence'). +token_metapredicate('ᶠ', 'brachylog_meta_find'). +token_metapredicate('ᵍ', 'brachylog_meta_groupby'). +token_metapredicate('ʰ', 'brachylog_meta_head'). +token_metapredicate('ⁱ', 'brachylog_meta_iterate'). +token_metapredicate('ʲ', ''). +token_metapredicate('ᵏ', ''). +token_metapredicate('ˡ', 'brachylog_meta_leftfold'). +token_metapredicate('ᵐ', 'brachylog_meta_map'). +token_metapredicate('ⁿ', 'brachylog_meta_nonexistence'). +token_metapredicate('ᵒ', 'brachylog_meta_orderby'). +token_metapredicate('ᵖ', ''). +token_metapredicate('ʳ', 'brachylog_meta_rightfold'). +token_metapredicate('ˢ', 'brachylog_meta_select'). +token_metapredicate('ᵗ', 'brachylog_meta_tail'). +token_metapredicate('ᵘ', 'brachylog_meta_unique'). +token_metapredicate('ᵛ', 'brachylog_meta_verify'). +token_metapredicate('ʷ', ''). +token_metapredicate('ˣ', ''). +token_metapredicate('ʸ', ''). +token_metapredicate('ᶻ', 'brachylog_meta_zip'). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/tests.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/tests.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,648 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- consult(brachylog). + + +:- begin_tests(predicates). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LESSEQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('lessequal_1', all(X == [2])) :- + run_from_atom('1≤2', _, X). +test('lessequal_2', all(X == [2])) :- + run_from_atom('_1≤2', _, X). +test('lessequal_3', all(X == [0])) :- + run_from_atom('0≤0', _, X). +test('lessequal_4', all(X == [13])) :- + run_from_atom('13≤13', _, X). +test('lessequal_5', all(X == [-42])) :- + run_from_atom('_42≤_42', _, X). +test('lessequal_6', all(X == [[1,2,3]])) :- + run_from_atom('[1,2,3]≤₁', _, X). +test('lessequal_7', all(X == [[-1,0,1]])) :- + run_from_atom('[_1,0,1]≤₁', _, X). +test('lessequal_8', all(X == [[-42,-23,-16]])) :- + run_from_atom('[_42,_23,_16]≤₁', _, X). +test('lessequal_9', all(X == [[1,1,3],[1,2,3],[1,3,3]])) :- + run_from_atom('[1,I,3]≤₁', _, X). +test('lessequal_10', fail) :- + run_from_atom('2≤1', _, _). +test('lessequal_11', fail) :- + run_from_atom('2≤_1', _, _). +test('lessequal_12', fail) :- + run_from_atom('[1,3,2]≤₁', _, _). +test('lessequal_13', fail) :- + run_from_atom('[1,I,_1]≤₁', _, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GREATEREQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('greaterequal_1', all(X == [1])) :- + run_from_atom('2≥1', _, X). +test('greaterequal_2', all(X == [-1])) :- + run_from_atom('2≥_1', _, X). +test('greaterequal_3', all(X == [0])) :- + run_from_atom('0≥0', _, X). +test('greaterequal_4', all(X == [13])) :- + run_from_atom('13≥13', _, X). +test('greaterequal_5', all(X == [-42])) :- + run_from_atom('_42≥_42', _, X). +test('greaterequal_6', all(X == [[3,2,1]])) :- + run_from_atom('[3,2,1]≥₁', _, X). +test('greaterequal_7', all(X == [[1,0,-1]])) :- + run_from_atom('[1,0,_1]≥₁', _, X). +test('greaterequal_8', all(X == [[-16,-23,-42]])) :- + run_from_atom('[_16,_23,_42]≥₁', _, X). +test('greaterequal_9', all(X == [[3,1,1],[3,2,1],[3,3,1]])) :- + run_from_atom('[3,I,1]≥₁', _, X). +test('greaterequal_10', fail) :- + run_from_atom('1≥2', _, _). +test('greaterequal_11', fail) :- + run_from_atom('_1≥2', _, _). +test('greaterequal_12', fail) :- + run_from_atom('[1,3,2]≥₁', _, _). +test('greaterequal_13', fail) :- + run_from_atom('[_1,I,1]≥₁', _, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CONTAINS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +% Nothing, same code as brachylog_in + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_IN +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('in_1', fail) :- + run_from_atom('∋', [], _). +test('in_2', fail) :- + run_from_atom('∋', "", _). +test('in_3', all(X == [0])) :- + run_from_atom('∋', 0, X). +test('in_4', all(X == [7])) :- + run_from_atom('∋', 7, X). +test('in_5', all(X == [7])) :- + run_from_atom('∋', '_7', X). +test('in_6', all(X == [1,0,2,3])) :- + run_from_atom('∋', 1023, X). +test('in_7', all(X == [1,0,2,3])) :- + run_from_atom('∋', [1,0,2,3], X). +test('in_8', all(X == [1023,"test"])) :- + run_from_atom('∋', [1023,"test"], X). +test('in_9', all(X == ["test"])) :- + run_from_atom('∋', ["test"], X). +test('in_10', all(X == ["t","e","s","t"])) :- + run_from_atom('∋', "test", X). +test('in_11', all(X == [1])) :- + run_from_atom('∋₀', 1023, X). +test('in_12', all(X == ["t"])) :- + run_from_atom('∋₀', "test", X). +test('in_13', all(X == [1023])) :- + run_from_atom('∋₀', [1023,"test"], X). +test('in_14', all(X == [0])) :- + run_from_atom('∋₁', 1023, X). +test('in_15', fail) :- + run_from_atom('∋₄', 1023, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SUPERSET +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +% Nothing, same code as brachylog_subset + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_SUBSET +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('subset_1', all(X == [[]])) :- + run_from_atom('⊇', [], X). +test('subset_2', all(X == [""])) :- + run_from_atom('⊇', "", X). +test('subset_3', all(X == [0])) :- + run_from_atom('⊇', 0, X). +test('subset_4', all(X == [7])) :- + run_from_atom('⊇', 7, X). +test('subset_5', all(X == [123,12,13,23,1,2,3])) :- + run_from_atom('⊇', 123, X). +test('subset_6', all(X == [[1,2,3],[1,2],[1,3],[2,3],[1],[2],[3],[]])) :- + run_from_atom('⊇', [1,2,3], X). +test('subset_7', all(X == ["test","tes","tet","tst","est","te","ts","tt","es","et","st","t","e","s","t",""])) :- + run_from_atom('⊇', "test", X). +test('subset_8', fail) :- + run_from_atom('⊇', [1,2,3], [1,5]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_REVERSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('reverse_1', all(X == [0])) :- + run_from_atom('↔', 0, X). +test('reverse_2', all(X == [[]])) :- + run_from_atom('↔', [], X). +test('reverse_3', all(X == [""])) :- + run_from_atom('↔', "", X). +test('reverse_4', all(X == [321])) :- + run_from_atom('↔', 123, X). +test('reverse_5', all(X == [321])) :- + run_from_atom('↔', 1230, X). +test('reverse_6', all(X == ["tset"])) :- + run_from_atom('↔', "test", X). +test('reverse_7', all(X == [[0,3,2,1]])) :- + run_from_atom('↔', [1,2,3,0], X). +test('reverse_8', all(X == [[1,2,3,2,1]])) :- + run_from_atom('↔?', '[1,2,3,I,J]', X). +test('reverse_9', all(X == [["a","b","c","b","a"]])) :- + run_from_atom('↔?', '["a","b","c",I,J]', X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CALL_PREDICATE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +% TODO + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CIRCULAR_PERMUTE_COUNTERCLOCKWISE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('circular_permute_counterclockwise_1', all(X == [[]])) :- + run_from_atom('↺', [], X). +test('circular_permute_counterclockwise_2', all(X == [""])) :- + run_from_atom('↺', "", X). +test('circular_permute_counterclockwise_3', all(X == [0])) :- + run_from_atom('↺', 0, X). +test('circular_permute_counterclockwise_4', all(X == [231])) :- + run_from_atom('↺', 123, X). +test('circular_permute_counterclockwise_5', all(X == ["estt"])) :- + run_from_atom('↺', "test", X). +test('circular_permute_counterclockwise_6', all(X == [[2,"test",1]])) :- + run_from_atom('↺', [1,2,"test"], X). +test('circular_permute_counterclockwise_7', all(X == [[4,5,6,1,2,3]])) :- + run_from_atom('↺₃', [1,2,3,4,5,6], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CIRCULAR_PERMUTE_CLOCKWISE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('circular_permute_clockwise_1', all(X == [[]])) :- + run_from_atom('↻', [], X). +test('circular_permute_clockwise_2', all(X == [""])) :- + run_from_atom('↻', "", X). +test('circular_permute_clockwise_3', all(X == [0])) :- + run_from_atom('↻', 0, X). +test('circular_permute_clockwise_4', all(X == [312])) :- + run_from_atom('↻', 123, X). +test('circular_permute_clockwise_5', all(X == ["ttes"])) :- + run_from_atom('↻', "test", X). +test('circular_permute_clockwise_6', all(X == [["test",1,2]])) :- + run_from_atom('↻', [1,2,"test"], X). +test('circular_permute_clockwise_7', all(X == [[4,5,6,1,2,3]])) :- + run_from_atom('↻₃', [1,2,3,4,5,6], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_ROOT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('root_1', all(X == [-1,1])) :- + run_from_atom('√', 1, X). +test('root_2', all(X == [0])) :- + run_from_atom('√', 0, X). +test('root_3', all(X == [-12,12])) :- + run_from_atom('√', 144, X). +test('root_4', all(X == [2.23606797749979])) :- + run_from_atom('√', 5, X). +test('root_5', throws(_)) :- + run_from_atom('√', '_5', _). +test('root_6', all(X == [2.04939015319192])) :- + run_from_atom('√', 4.2, X). +test('root_7', all(X == [3])) :- + run_from_atom('√₃', 27, X). +test('root_8', all(X == [-3])) :- + run_from_atom('√₃', '_27', X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_CEIL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('ceil_1', fail) :- + run_from_atom('⌉', [], _). +test('ceil_2', all(X == [3])) :- + run_from_atom('⌉', [1,2,3], X). +test('ceil_3', all(X == [-5])) :- + run_from_atom('⌉', '[_9,_5,_13]', X). +test('ceil_4', all(X == ["test"])) :- + run_from_atom('⌉', ["test",2,3], X). +test('ceil_5', all(X == ["z"])) :- + run_from_atom('⌉', ["test","z"], X). +test('ceil_6', all(X == [123])) :- + run_from_atom('⌉₁', 123, X). +test('ceil_7', all(X == [124])) :- + run_from_atom('⌉₁', 123.45, X). +test('ceil_8', all(X == [-123])) :- + run_from_atom('⌉₁', '_123.45', X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FLOOR +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('floor_1', fail) :- + run_from_atom('⌋', [], _). +test('floor_2', all(X == [1])) :- + run_from_atom('⌋', [1,2,3], X). +test('floor_3', all(X == [-13])) :- + run_from_atom('⌋', '[_9,_5,_13]', X). +test('floor_4', all(X == [2])) :- + run_from_atom('⌋', ["test",2,3], X). +test('floor_5', all(X == ["test"])) :- + run_from_atom('⌋', ["test","z"], X). +test('floor_6', all(X == [123])) :- + run_from_atom('⌋₁', 123, X). +test('floor_7', all(X == [123])) :- + run_from_atom('⌋₁', 123.45, X). +test('floor_8', all(X == [-124])) :- + run_from_atom('⌋₁', '_123.45', X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANGE_ASCENDING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('range_ascending_1', all(X == [[0]])) :- + run_from_atom('⟦', 0, X). +test('range_ascending_2', all(X == [[0,1,2,3,4,5]])) :- + run_from_atom('⟦', 5, X). +test('range_ascending_3', all(X == [[-5,-4,-3,-2,-1,0]])) :- + run_from_atom('⟦', '_5', X). +test('range_ascending_4', all(X == [[1,2,3,4,5]])) :- + run_from_atom('⟦₁', 5, X). +test('range_ascending_5', all(X == [[9,10,11,12,13]])) :- + run_from_atom('⟦₂', [9,13], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_RANGE_DESCENDING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('range_descending_1', all(X == [[0]])) :- + run_from_atom('⟧', 0, X). +test('range_descending_2', all(X == [[5,4,3,2,1,0]])) :- + run_from_atom('⟧', 5, X). +test('range_descending_3', all(X == [[0,-1,-2,-3,-4,-5]])) :- + run_from_atom('⟧', '_5', X). +test('range_descending_4', all(X == [[5,4,3,2,1]])) :- + run_from_atom('⟧₁', 5, X). +test('range_descending_5', all(X == [[13,12,11,10,9]])) :- + run_from_atom('⟧₂', [9,13], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_NATURAL_INTEGER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('natural_integer_1', all(X == [0])) :- + run_from_atom('ℕ', 0, X). +test('natural_integer_2', all(X == [42])) :- + run_from_atom('ℕ', 42, X). +test('natural_integer_3', fail) :- + run_from_atom('ℕ', "test", _). +test('natural_integer_4', fail) :- + run_from_atom('ℕ', '_3', _). +test('natural_integer_5', fail) :- + run_from_atom('ℕ', [1,2], _). +test('natural_integer_6', fail) :- + run_from_atom('ℕ', 4.2, _). +test('natural_integer_7', all(X == [42])) :- + run_from_atom('ℕ₄₂', 42, X). +test('natural_integer_8', fail) :- + run_from_atom('ℕ₄₂', 41, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_INTEGER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('integer_1', all(X == [0])) :- + run_from_atom('ℤ', 0, X). +test('integer_2', all(X == [42])) :- + run_from_atom('ℤ', 42, X). +test('integer_3', fail) :- + run_from_atom('ℤ', "test", _). +test('integer_4', all(X == [-3])) :- + run_from_atom('ℤ', '_3', X). +test('integer_5', fail) :- + run_from_atom('ℤ', [1,2], _). +test('integer_6', fail) :- + run_from_atom('ℤ', 4.2, _). +test('integer_7', all(X == [-42])) :- + run_from_atom('ℤ₄₂', '_42', X). +test('integer_8', fail) :- + run_from_atom('ℤ₄₂', '_41', _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_FLOAT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('float_1', all(X == [4.2])) :- + run_from_atom('ℝ', 4.2, X). +test('float_2', all(X == [0.0])) :- + run_from_atom('ℝ', 0.0, X). +test('float_3', all(X == [-4.2])) :- + run_from_atom('ℝ', '_4.2', X). +test('float_4', fail) :- + run_from_atom('ℝ', 0, _). +test('float_5', fail) :- + run_from_atom('ℝ', 42, _). +test('float_6', all(X == [42])) :- + run_from_atom('ℝ₁', 42, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_EMPTY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('empty_1', nondet) :- + run_from_atom('∅', [], _). +test('empty_2', nondet) :- + run_from_atom('∅', 0, _). +test('empty_3', nondet) :- + run_from_atom('∅', "", _). +test('empty_4', nondet) :- + run_from_atom('∅', 0.0, _). +test('empty_5', fail) :- + run_from_atom('∅', [1], _). +test('empty_6', fail) :- + run_from_atom('∅', 1, _). +test('empty_7', fail) :- + run_from_atom('∅', "a", _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DIFFERENT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('different_1', all(X == [12345])) :- + run_from_atom('≠', 12345, X). +test('different_1', fail) :- + run_from_atom('≠', 12344, _). +test('different_1', all(X == [[1,2,3]])) :- + run_from_atom('≠', [1,2,3], X). +test('different_1', fail) :- + run_from_atom('≠', [1,2,1], _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_INTEGER_DIVISION +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('integer_division_1', all(X == [3])) :- + run_from_atom('÷', [6,2], X). +test('integer_division_2', all(X == [3])) :- + run_from_atom('÷', [7,2], X). +test('integer_division_3', all(X == [-3])) :- + run_from_atom('÷', '[_6,2]', X). +test('integer_division_1', fail) :- + run_from_atom('÷', '[6,0]', _). +test('integer_division_1', all(X == [0])) :- + run_from_atom('÷', '[0,_42]', X). +test('integer_division_1', all(X == [3])) :- + run_from_atom('÷', [6.2,2], X). +test('integer_division_1', all(X == [2])) :- + run_from_atom('÷₃', 6, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MULTIPLY +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('multiply_1', all(X == [1])) :- + run_from_atom('×', [], X). +test('multiply_2', all(X == [12])) :- + run_from_atom('×', [6,2], X). +test('multiply_3', all(X == [12])) :- + run_from_atom('×', [2,6], X). +test('multiply_4', all(X == [-12])) :- + run_from_atom('×', '[_6,2]', X). +test('multiply_5', all(X == [24])) :- + run_from_atom('×', [2,3,4], X). +test('multiply_6', all(X == [0])) :- + run_from_atom('×', '[0,_42]', X). +test('multiply_7', all(X == [12.4])) :- + run_from_atom('×', [6.2,2], X). +test('multiply_8', all(X == [18])) :- + run_from_atom('×₃', 6, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MODULO +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('modulo_1', all(X == [1])) :- + run_from_atom('%', [4,3], X). +test('modulo_2', all(X == [0])) :- + run_from_atom('%', [4,2], X). +test('modulo_3', all(X == [4])) :- + run_from_atom('%', [42,19], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_EXP +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('exp_1', all(X == [22026.465794806718])) :- + run_from_atom('*', 10, X). +test('exp_2', all(X == [2.302585092994046])) :- + run_from_atom('*₁', 10, X). +test('exp_3', all(X == [-0.8390715290764524])) :- + run_from_atom('*₂', 10, X). +test('exp_4', all(X == [-0.5440211108893698])) :- + run_from_atom('*₃', 10, X). +test('exp_5', all(X == [0.6483608274590866])) :- + run_from_atom('*₄', 10, X). +test('exp_6', all(X == [1.0471975511965979])) :- + run_from_atom('*₅', 0.5, X). +test('exp_7', all(X == [0.5235987755982989])) :- + run_from_atom('*₆', 0.5, X). +test('exp_8', all(X == [1.4711276743037347])) :- + run_from_atom('*₇', 10, X). +test('exp_9', all(X == [11013.232920103323])) :- + run_from_atom('*₈', 10, X). +test('exp_10', all(X == [11013.232874703393])) :- + run_from_atom('*₉', 10, X). +test('exp_11', all(X == [0.9999999958776927])) :- + run_from_atom('*₁₀', 10, X). +test('exp_12', all(X == [2.993222846126381])) :- + run_from_atom('*₁₁', 10, X). +test('exp_13', all(X == [2.99822295029797])) :- + run_from_atom('*₁₂', 10, X). +test('exp_14', all(X == [0.5493061443340549])) :- + run_from_atom('*₁₃', 0.5, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PLUS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('plus_1', all(X == [3])) :- + run_from_atom('+', [1,2], X). +test('plus_2', all(X == [2])) :- + run_from_atom('+', '[_3,5]', X). +test('plus_3', all(X == [-5])) :- + run_from_atom('+', '[_3,_2]', X). +test('plus_4', all(X == [21])) :- + run_from_atom('+', [1,2,3,4,5,6], X). +test('plus_5', all(X == [4.6])) :- + run_from_atom('+', [1.2,3.4], X). +test('plus_6', all(X == [13])) :- + run_from_atom('+', [13,0,0,0,0], X). +test('plus_7', all(X == [67])) :- + run_from_atom('+₄₂', 25, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_MINUS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('minus_1', all(X == [-1])) :- + run_from_atom('-', [1,2], X). +test('minus_2', all(X == [-8])) :- + run_from_atom('-', '[_3,5]', X). +test('minus_3', all(X == [2])) :- + run_from_atom('-', '[_1,_3]', X). +test('minus_4', all(X == [-3])) :- + run_from_atom('-', [1,2,3,4,5,6], X). +test('minus_5', all(X == [-2.2])) :- + run_from_atom('-', [1.2,3.4], X). +test('minus_6', all(X == [13])) :- + run_from_atom('-', [13,0,0,0,0], X). +test('minus_7', all(X == [-17])) :- + run_from_atom('-₄₂', 25, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_DIVIDE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('divide_1', all(X == [0.5])) :- + run_from_atom('/', [1,2], X). +test('divide_2', all(X == [3])) :- + run_from_atom('/', [6,2], X). +test('divide_3', all(X == [-0.5])) :- + run_from_atom('/', '[1,_2]', X). +test('divide_4', all(X == [0.1111111111111111])) :- + run_from_atom('/₁', 9, X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LESS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('less_1', all(X == [2])) :- + run_from_atom('1<2', _, X). +test('less_2', all(X == [2])) :- + run_from_atom('_1<2', _, X). +test('less_3', fail) :- + run_from_atom('0<0', _, _). +test('less_4', fail) :- + run_from_atom('13<13', _, _). +test('less_5', fail) :- + run_from_atom('_42<_42', _, _). +test('less_6', all(X == [[1,2,3]])) :- + run_from_atom('[1,2,3]<₁', _, X). +test('less_7', all(X == [[-1,0,1]])) :- + run_from_atom('[_1,0,1]<₁', _, X). +test('less_8', all(X == [[-42,-23,-16]])) :- + run_from_atom('[_42,_23,_16]<₁', _, X). +test('less_9', all(X == [[1,2,3]])) :- + run_from_atom('[1,I,3]<₁', _, X). +test('less_10', fail) :- + run_from_atom('2<1', _, _). +test('less_11', fail) :- + run_from_atom('2<_1', _, _). +test('less_12', fail) :- + run_from_atom('[1,3,2]<₁', _, _). +test('less_13', fail) :- + run_from_atom('[1,I,_1]<₁', _, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_EQUAL +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('equal_1', all(X == [1111])) :- + run_from_atom('=', 1111, X). +test('equal_2', all(X == [[]])) :- + run_from_atom('=', [], X). +test('equal_3', all(X == [0])) :- + run_from_atom('=', 0, X). +test('equal_4', all(X == [[42,42,42,42]])) :- + run_from_atom('=', '[X,Y,42,Z]', X). +test('equal_5', fail) :- + run_from_atom('=', [1,1,1,2,1], _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_GREATER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('greater_1', all(X == [1])) :- + run_from_atom('2>1', _, X). +test('greater_2', all(X == [-1])) :- + run_from_atom('2>_1', _, X). +test('greater_3', fail) :- + run_from_atom('0>0', _, _). +test('greater_4', fail) :- + run_from_atom('13>13', _, _). +test('greater_5', fail) :- + run_from_atom('_42>_42', _, _). +test('greater_6', all(X == [[3,2,1]])) :- + run_from_atom('[3,2,1]>₁', _, X). +test('greater_7', all(X == [[1,0,-1]])) :- + run_from_atom('[1,0,_1]>₁', _, X). +test('greater_8', all(X == [[-16,-23,-42]])) :- + run_from_atom('[_16,_23,_42]>₁', _, X). +test('greater_9', all(X == [[3,2,1]])) :- + run_from_atom('[3,I,1]>₁', _, X). +test('greater_10', fail) :- + run_from_atom('1>2', _, _). +test('greater_11', fail) :- + run_from_atom('_1>2', _, _). +test('greater_12', fail) :- + run_from_atom('[1,3,2]>₁', _, _). +test('greater_13', fail) :- + run_from_atom('[_1,I,1]>₁', _, _). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_TRANSPOSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('transpose_1', all(X == [[[1,4,7],[2,5,8],[3,6,9]]])) :- + run_from_atom('\\', [[1,2,3],[4,5,6],[7,8,9]], X). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_POWER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +test('power_1', all(X == [8])) :- + run_from_atom('^', [2,3], X). +test('power_2', all(X == [-8])) :- + run_from_atom('^', '[_2,3]', X). +test('power_3', all(X == [1])) :- + run_from_atom('^', [1,50], X). +test('power_4', all(X == [0])) :- + run_from_atom('^', [0,42], X). +test('power_5', all(X == [1])) :- + run_from_atom('^', [7,0], X). +test('power_6', all(X == [49])) :- + run_from_atom('^₂', 7, X). + + +:- end_tests(predicates). + + +% Useful templates +test('_', all(X == [])) :- + run_from_atom('', _, X). + +test('_', fail) :- + run_from_atom('', _, _). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/tokenize.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/tokenize.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,341 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(tokenize, [tokenize/2]). + +:- use_module(symbols). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize([], []). +tokenize([' '|T], T2) :- + tokenize(T, T2). +tokenize([Variable|T], ['variable':VariableName:'sup':Sup|T2]) :- + is_variable_character(Variable), + tokenize_variable([Variable|T], Rest, VariableName), + tokenize_superscript(Rest, Rest2, Sup), + tokenize(Rest2, T2). +tokenize([Variable|T], ['variable':R|T2]) :- + ( is_variable_character_dot_above(Variable) + -> token_variable(Variable, RealVariable), + tokenize_superscript(T, Rest, Sup), + R = RealVariable:'sup':Sup + ; is_variable_character_dot_below(Variable) + -> token_variable(Variable, R), + Rest = T + ), + tokenize(Rest, T2). +tokenize([Variable|T], ['variable':RealVariable|T2]) :- + is_math_constant_character(Variable), + token_variable(Variable, RealVariable), + tokenize(T, T2). +tokenize([H|T], ['variable':'Input':'sup':Sup|T2]) :- + is_input_character(H), + tokenize_superscript(T, Rest, Sup), + tokenize(Rest, T2). +tokenize([H|T], ['variable':'Output':'sup':Sup|T2]) :- + is_output_character(H), + tokenize_superscript(T, Rest, Sup), + tokenize(Rest, T2). +tokenize([Modifier,Predicate|T], ['predicate':PredName:Sub|T2]) :- + is_modifier_character(Modifier), + \+ (is_variable_character(Predicate)), + atomic_list_concat([Modifier,Predicate], Pred), + token_predicate(Pred, PredName), + tokenize_subscript(T, Rest, Sub), + tokenize(Rest, T2). +tokenize([Predicate|T], ['predicate':PredName:Sub|T2]) :- + is_predicate_character(Predicate), + token_predicate(Predicate, PredName), + tokenize_subscript(T, Rest, Sub), + tokenize(Rest, T2). +tokenize([MetaPred|T], ['metapredicate':PredName:Sup|T2]) :- + is_metapredicate_character(MetaPred), + token_metapredicate(MetaPred, PredName), + tokenize_superscript(T, Rest, Sup), + tokenize(Rest, T2). +tokenize(['"'|T], ['variable':Variable|T2]) :- + tokenize_string(['"'|T], Rest, Variable), + tokenize(Rest, T2). +tokenize(['_',Digit|T], ['variable':Type:N|T2]) :- + is_digit_character(Digit), + tokenize_number([Digit|T] ,Rest, Type:X), + N is -X, + tokenize(Rest, T2). +tokenize(['_','_'|T], T2) :- + tokenize(T, T2). +tokenize([Digit|T], ['variable':Type:X|T2]) :- + is_digit_character(Digit), + tokenize_number([Digit|T], Rest, Type:X), + tokenize(Rest, T2). +tokenize(['['|T], ['variable':List|T2]) :- + tokenize_list(['['|T], Rest, List), + tokenize(Rest, T2). +tokenize([Modifier,Variable|T], ['variable':RealVariable|T2]) :- + is_modifier_character(Modifier), + is_variable_character(Variable), + token_variable(Modifier:Variable, RealVariable), + tokenize(T, T2). +tokenize([ControlFlow|T], ['control':ControlFlow|T2]) :- + is_control_character(ControlFlow), + tokenize(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_VARIABLE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_variable([], [], ''). +tokenize_variable([H|T], R, Name) :- + ( is_variable_character(H) -> + tokenize_variable(T, R, TName), + atomic_list_concat([H, TName], Name) + ; Name = '', + R = [H|T] + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_STRING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_string(['"'|T], Rest, 'string':T2) :- + tokenize_string_(T, Rest, T2). + +tokenize_string_([], [], []). +tokenize_string_([X,'"'|Rest], Rest, [X]) :- + X \= '\\', + X \= '"', + Rest \= ['"'|_], + !. +tokenize_string_(['\\','"'|T], Rest, ['"'|T2]) :- + tokenize_string_(T, Rest, T2). +tokenize_string_(['"','"'|T], Rest, ['"'|T2]) :- + tokenize_string_(T, Rest, T2). +tokenize_string_([X|T], Rest, L) :- + ( X \= '"' -> + L = [X|T2], + tokenize_string_(T, Rest, T2) + ; Rest = T, + L = [] + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_NUMBER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_number(N, Rest, Type:Number) :- + tokenize_number_(N, Rest, T2), + ( member('.', T2), + !, + Type = 'float' + ; Type = 'integer' + ), + atomic_list_concat(T2, A), + atom_number(A, Number). + +tokenize_number_([], [], []). +tokenize_number_(['.',I|T], Rest, ['.',J|T2]) :- + is_digit_character(I), + atom_number(I, J), + tokenize_integer(T, Rest, T2). +tokenize_number_(['.'], ['.'], []). +tokenize_number_(['.',X|T], ['.',X|T], []) :- + \+ (is_digit_character(X)). +tokenize_number_([X|T], [X|T], []) :- + \+ (is_digit_character(X)), + X \= '.'. +tokenize_number_([I|T], Rest, [J|T2]) :- + is_digit_character(I), + atom_number(I, J), + tokenize_number_(T, Rest, T2). + +tokenize_integer([], [], []). +tokenize_integer([I|T], Rest, [J|T2]) :- + is_digit_character(I), + atom_number(I, J), + tokenize_integer(T, Rest, T2). +tokenize_integer([X|T], [X|T], []) :- + \+ (is_digit_character(X)). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_LIST +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_list(['['|T], Rest, List) :- + isolate_list(T, L, Rest), + tokenize(L, List). + +isolate_list(T, List, Rest) :- + isolate_list(T, 1, [], L, Rest), + reverse(L, List). +isolate_list([], _, L, L, []). +isolate_list([']'|T], 1, L, L, T). +isolate_list([']'|T], X, L, M, Rest) :- + X > 1, + Y is X - 1, + isolate_list(T, Y, [']'|L], M, Rest). +isolate_list(['['|T], X, L, M, Rest) :- + Y is X + 1, + isolate_list(T, Y, ['['|L], M, Rest). +isolate_list([H|T], X, L, M, Rest) :- + H \= '[', + H \= ']', + isolate_list(T, X, [H|L], M, Rest). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_SUBSCRIPT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_subscript(L, Rest, Sub) :- + tokenize_subscript_(L, Rest, LSub), + ( LSub = 'first' -> + Sub = LSub + ; LSub = 'last' -> + Sub = 'last' + ; LSub = [] -> + Sub = 'default' + ; maplist(number_codes, LSub, LC), + append(LC, C), + number_codes(ISub, C), + term_to_atom('integer':ISub, Sub) + ). + +tokenize_subscript_([], [], []). +tokenize_subscript_([H|T], Rest, Ds) :- + ( is_subscript_character(H, D) -> + tokenize_subscript_(T, Rest, TDs), + Ds = [D|TDs] + ; is_subscript_parenthesis(H, D) -> + Rest = T, + Ds = D + ; Rest = [H|T], + Ds = [] + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TOKENIZE_SUPERSCRIPT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +tokenize_superscript(L, Rest, Sup) :- + tokenize_superscript_(L, Rest, LSup), + ( LSup = 'first' -> + Sup = LSup + ; LSup = 'last' -> + Sup = 'last' + ; LSup = [] -> + Sup = 'default' + ; maplist(number_codes, LSup, LC), + append(LC, C), + number_codes(ISup, C), + term_to_atom('integer':ISup, Sup) + ). + +tokenize_superscript_([], [], []). +tokenize_superscript_([H|T], Rest, Ds) :- + ( is_superscript_character(H, D) -> + tokenize_superscript_(T, Rest, TDs), + Ds = [D|TDs] + ; is_superscript_parenthesis(H, D) -> + Rest = T, + Ds = D + ; Rest = [H|T], + Ds = [] + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + IS_X_CHARACTER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +is_variable_character(X) :- + member(X, ['A', 'B', 'C', 'D', 'E', + 'F', 'G', 'H', 'I', 'J', + 'K', 'L', 'M', 'N', 'O', + 'P', 'Q', 'R', 'S', 'T', + 'U', 'V', 'W', 'X', 'Y', 'Z']). + +is_variable_character_dot_below(X) :- + member(X, ['Ạ', 'Ḅ', 'Ḍ', 'Ẹ', + 'Ḥ', 'Ị', 'Ḳ', 'Ḷ', + 'Ṃ', 'Ṇ', 'Ọ', 'Ṛ', + 'Ṣ', 'Ṭ', 'Ụ', 'Ṿ', + 'Ẉ', 'Ỵ', 'Ẓ']). + +is_variable_character_dot_above(X) :- + member(X, ['Ȧ', 'Ḃ', 'Ċ', 'Ḋ', 'Ė', + 'Ḟ', 'Ġ', 'Ḣ', 'İ', 'Ṁ', + 'Ṅ', 'Ȯ', 'Ṗ', 'Ṙ', 'Ṡ', + 'Ṫ', 'Ẇ', 'Ẋ', 'Ẏ', 'Ż']). + +is_digit_character(X) :- + member(X, ['0', '1', '2', '3', '4', + '5', '6', '7', '8', '9']). + +is_predicate_character(X) :- + member(X, ['≤', '≥', '∈', '∋', '⊆', '⊇', + '↔', '↰', '↺', + '↻', '√', '⌉', '⌋', '⟦', '⟧', + 'ℕ', 'ℤ', 'ℝ', '∅', '≠', '≡', + '÷', '×', '%', '*', '+', + '-', '/', '<', '=', '>', '\\', + '^', 'a', 'b', 'c', 'd', 'e', + 'f', 'g', 'h', 'i', 'j', 'k', + 'l', 'm', 'n', 'o', 'p', 'q', + 'r', 's', 't', 'u', 'v', 'w', + 'x', 'y', 'z', 'ạ', 'ḅ', 'ḍ', + 'ẹ', 'ḥ', 'ị', 'ḳ', 'ḷ', 'ṃ', + 'ṇ', 'ọ', 'ṛ', 'ṣ', 'ṭ', 'ụ', + 'ṿ', 'ẉ', 'ỵ', 'ẓ', 'ȧ', 'ḃ', + 'ċ', 'ḋ', 'ė', 'ḟ', 'ġ', 'ḣ', + 'ṁ', 'ṅ', 'ȯ', 'ṗ', 'ṙ', 'ṡ', + 'ṫ', 'ẇ', 'ẋ', 'ẏ', 'ż', '≜']). + +is_math_constant_character(X) :- + member(X, ['π', 'φ']). + +is_modifier_character(X) :- + member(X, ['$', '@', '#']). + +is_input_character('?'). + +is_output_character('.'). + +is_metapredicate_character(X) :- + member(X, ['ᵃ', 'ᵇ', 'ᶜ', 'ᵈ', 'ᵉ', + 'ᶠ', 'ᵍ', 'ʰ', 'ⁱ', 'ʲ', + 'ᵏ', 'ˡ', 'ᵐ', 'ⁿ', 'ᵒ', + 'ᵖ', 'ʳ', 'ˢ', 'ᵗ', 'ᵘ', + 'ᵛ', 'ʷ', 'ˣ', 'ʸ', 'ᶻ']). + +is_subscript_character(C, D) :- + nth0(D, ['₀','₁','₂','₃','₄', + '₅','₆','₇','₈','₉'], C). + +is_subscript_parenthesis('₍', 'first'). +is_subscript_parenthesis('₎', 'last'). + +is_superscript_character(C, D) :- + nth0(D, ['⁰','¹','²','³','⁴', + '⁵','⁶','⁷','⁸','⁹'], C). + +is_superscript_parenthesis('⁽', 'first'). +is_superscript_parenthesis('⁾', 'last'). + +is_control_character(X) :- + member(X, ['∧', '∨', '⊥', '\n', '!', '↖', '↙', + '\'', '(', ')', ',', ':', + ':', '|', '{', '}', '`', + '¬', '~', ';', '&', '⟨', '⟩']). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/transpile.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/transpile.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,641 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(transpile, [parse/2, + parse_no_file/2, + parse_argument/2, + contains_write/1 + ]). + +:- use_module(tokenize). +:- use_module(symbols). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + PARSE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +parse(Code, TranspiledPath) :- + parse_no_file(Code, Predicates), + open(TranspiledPath, write, File), + maplist(write_to_file(File), Predicates), + close(File). + +parse_no_file(Code, Predicates) :- + atom_chars(Code, SplittedCode), + tokenize(SplittedCode, TokensNoOutputs), + append_trailing_output(TokensNoOutputs, Tokens), + fix_predicates(Tokens, FixedPredicates), + fix_metapredicates(FixedPredicates, FixedMetapredicates), + fill_implicit_variables(FixedMetapredicates, FilledTokens), + fix_variables_superscripts(FilledTokens, FixedVariables, GlobalVariables), + fix_lists(FixedVariables, FixedLists), + fix_forks(FixedLists, FixedForks), + fix_arrows(FixedForks, Program), + atomic_list_concat(GlobalVariables, ',', G), + atomic_list_concat(['[', G, ']'], GlobalVariablesAtom), + transpile(Program, Predicates, GlobalVariablesAtom), + !. + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + PARSE_ARGUMENT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +parse_argument(Arg, Term) :- + ( atom(Arg), + AtomArg = Arg + ; \+ atom(Arg), + term_to_atom(Arg, AtomArg) + ), + atom_chars(AtomArg, SplittedArg), + tokenize(SplittedArg, Token), + fix_variables_superscripts(Token, FixedSuperscripts, _), + fix_lists(FixedSuperscripts, Program), + transpile(Program, Parsed, '[]'), + !, + reverse(Parsed, [TempMainPredicate|_]), + nth0(3, TempMainPredicate, Atom), + atom_concat(',\n ', AtomT, Atom), + atom_concat(ParsedArg, ' = Var_Input_Local', AtomT), + term_to_atom(Term, ParsedArg) + ; + throw('Incorrect variable format.'). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + APPEND_TRAILING_OUTPUT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +append_trailing_output([], ['variable':'Output':'sup':'default']). +append_trailing_output(['control':'\n'|T], ['variable':'Output':'sup':'default','control':'\n'|T2]) :- + append_trailing_output(T, T2). +append_trailing_output(['control':'}'|T], ['variable':'Output':'sup':'default','control':'}'|T2]) :- + append_trailing_output(T, T2). +append_trailing_output(['control':'⟩'|T], ['variable':'Output':'sup':'default','control':'⟩'|T2]) :- + append_trailing_output(T, T2). +append_trailing_output(['control':'|'|T], ['variable':'Output':'sup':'default','control':'|'|T2]) :- + append_trailing_output(T, T2). +append_trailing_output([H|T], [H|T2]) :- + H \= 'control':'\n', + H \= 'control':'}', + H \= 'control':'⟩', + H \= 'control':'|', + append_trailing_output(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_PREDICATES'⟨', '⟩' +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_predicates(Tokens, FixedPredicates) :- + fix_predicates(Tokens, 1, L), + append(L, FixedPredicates). + +fix_predicates([], _, [[]]). +fix_predicates(['control':'{'|T], I, [['predicate':PredName:0|Rest], ['control':'\n'|Predicate]|AllOtherPredicates]) :- + atomic_list_concat(['brachylog_predicate_',I], PredName), + J is I + 1, + fix_predicates_(T, J, [Predicate|OtherPredicates1], Z, Remaining), + fix_predicates(Remaining, Z, [Rest|OtherPredicates2]), + append(OtherPredicates1, OtherPredicates2, AllOtherPredicates). +fix_predicates(['control':'⟨'|T], I, [['predicate':PredName:0|Rest], ['control':'\n','fork':'start'|Predicate]|AllOtherPredicates]) :- + atomic_list_concat(['brachylog_predicate_',I], PredName), + J is I + 1, + fix_predicates_(T, J, [Predicate|OtherPredicates1], Z, Remaining), + fix_predicates(Remaining, Z, [Rest|OtherPredicates2]), + append(OtherPredicates1, OtherPredicates2, AllOtherPredicates). +fix_predicates(['control':'\n'|T], I, [[],['control':'\n'|Rest]|OtherPredicates]) :- + J is I + 1, + fix_predicates(T, J, [Rest|OtherPredicates]). +fix_predicates([Type:A|T], I, [[Type:A|Rest]|OtherPredicates]) :- + \+ (Type = 'control', A = '{'), + \+ (Type = 'control', A = '}'), + \+ (Type = 'control', A = '⟨'), + \+ (Type = 'control', A = '⟩'), + \+ (Type = 'control', A = '\n'), + fix_predicates(T, I, [Rest|OtherPredicates]). + +fix_predicates_([], _, [[]]). +fix_predicates_(['control':'{'|T], I, [['predicate':PredName:0|Rest], ['control':'\n'|Predicate]|AllOtherPredicates], Z, Remaining) :- + atomic_list_concat(['brachylog_predicate_',I], PredName), + J is I + 1, + fix_predicates_(T, J, [Predicate|OtherPredicates1], Z2, Remaining2), + fix_predicates_(Remaining2, Z2, [Rest|OtherPredicates2], Z, Remaining), + append(OtherPredicates1, OtherPredicates2, AllOtherPredicates). +fix_predicates_(['control':'⟨'|T], I, [['predicate':PredName:0|Rest], ['control':'\n','fork':'start'|Predicate]|AllOtherPredicates], Z, Remaining) :- + atomic_list_concat(['brachylog_predicate_',I], PredName), + J is I + 1, + fix_predicates_(T, J, [Predicate|OtherPredicates1], Z2, Remaining2), + fix_predicates_(Remaining2, Z2, [Rest|OtherPredicates2], Z, Remaining), + append(OtherPredicates1, OtherPredicates2, AllOtherPredicates). +fix_predicates_(['control':'}'|T], I, [[]], I, T). +fix_predicates_(['control':'⟩'|T], I, [['fork':'end']], I, T). +fix_predicates_([Type:A|T], I, [[Type:A|Rest]|OtherPredicates], Z, Remaining) :- + \+ (Type = 'control', A = '{'), + \+ (Type = 'control', A = '}'), + \+ (Type = 'control', A = '⟨'), + \+ (Type = 'control', A = '⟩'), + \+ (Type = 'control', A = '\n'), + fix_predicates_(T, I, [Rest|OtherPredicates], Z, Remaining). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_METAPREDICATES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_metapredicates([], []). +fix_metapredicates(['predicate':PredName:Sub,'metapredicate':MetapredName:Sup|T], ['predicate':PredName:Sub:MetapredName:Sup|T2]) :- + fix_metapredicates(T, T2). +fix_metapredicates(['predicate':PredName:Sub|T], ['predicate':PredName:Sub:'no':0|T2]) :- + fix_metapredicates(T, T2). +fix_metapredicates([H|T], [H|T2]) :- + fix_metapredicates(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FILL_IMPLICIT_VARIABLES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fill_implicit_variables(Tokens, Program) :- + fill_implicit_variables(Tokens, 0, Program). + +fill_implicit_variables([], _, []). +fill_implicit_variables(['control':':','predicate':A|T], I, ['control':':','predicate':A|T2]) :- + fill_implicit_variables(T, I, T2). +fill_implicit_variables(['predicate':A,Type:B|T], I, ['predicate':A,'variable':V|T2]) :- + Type \= 'variable', + atom_concat('V', I, V), + J is I + 1, + fill_implicit_variables([Type:B|T], J, T2). +fill_implicit_variables(['predicate':A], I, ['predicate':A,'variable':V]) :- + atom_concat('V', I, V). +fill_implicit_variables(['predicate':A,'variable':B|T], I, ['predicate':A,'variable':B|T2]) :- + fill_implicit_variables(T, I, T2). +fill_implicit_variables(['control':H,Type:B|T], I, ['control':H,'variable':V|T2]) :- + Type \= 'variable', + ( H = '∧' + ; H = '∨' + ), + atom_concat('V', I, V), + J is I + 1, + fill_implicit_variables([Type:B|T], J, T2). +fill_implicit_variables(['control':H,'variable':B,Type:C|T], I, ['control':H,'variable':B,'variable':V|T2]) :- + Type \= 'variable', + ( H = '↖' + ; H = '↙' + ), + atom_concat('V', I, V), + J is I + 1, + fill_implicit_variables([Type:C|T], J, T2). +fill_implicit_variables([Type:A|T], I, [Type:A|T2]) :- + Type \= 'predicate', + \+ (Type = 'control', A = ':', T = ['predicate':_|_]), + \+ (Type = 'control', A = '∧', T \= ['variable':_|_]), + \+ (Type = 'control', A = '∨', T \= ['variable':_|_]), + \+ (Type = 'control', A = '↖', T \= ['variable':_|_]), + \+ (Type = 'control', A = '↙', T \= ['variable':_|_]), + fill_implicit_variables(T, I, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_VARIABLES_SUPERSCRIPTS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_variables_superscripts(Input, Output, GlobalVariables) :- + fix_variables_superscripts_(Input, Output, GlobVars), + sort(GlobVars, GlobalVariables). % Remove duplicates + +fix_variables_superscripts_([], [], []). +fix_variables_superscripts_(['variable':A:'sup':Sup|T], ['variable':V|T2], [V|GlobalVariables]) :- + atomic_list_concat(['integer', SupAtom], ':', Sup), + atom_number(SupAtom, J), + atomic_list_concat(['Var_',A,'_',J], V), + fix_variables_superscripts_(T, T2, GlobalVariables). +fix_variables_superscripts_(['variable':A:'sup':'default'|T], ['variable':V|T2], GlobalVariables) :- + atomic_list_concat(['Var_',A,'_Local'], V), + fix_variables_superscripts_(T, T2, GlobalVariables). +fix_variables_superscripts_(['variable':List|T], ['variable':FixedList|T2], GlobalVariables) :- + is_list(List), + fix_variables_superscripts_(List, FixedList, Vars), + fix_variables_superscripts_(T, T2, GlobalVariables2), + append(Vars, GlobalVariables2, GlobalVariables). +fix_variables_superscripts_([X|T], [X|T2], GlobalVariables) :- + fix_variables_superscripts_(T, T2, GlobalVariables). + + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_LISTS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_lists([], []). +fix_lists(['variable':List|T], ['variable':FixedList|T2]) :- + is_list(List), + fix_list(List, FixedList), + fix_lists(T, T2). +fix_lists([X|T], [X|T2]) :- + ( X = 'variable':L, + \+ (is_list(L)) + ; X \= 'variable':_ + ), + fix_lists(T, T2). + +fix_list([], []). +fix_list(['control':','|T], T2) :- + fix_list(T, T2). +fix_list([X|T], [Y|T2]) :- + X \= 'control':',', + ( X = 'variable':L, + is_list(L), + fix_list(L, Y) + ; X = 'variable':Y + ; X = 'predicate':_, + Y = X + ; Y = X + ), + fix_list(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_FORKS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_forks(L, Z) :- + fix_forks(L, 0, Z). + +fix_forks([], _, []). % Ignore each useless implicit var after +fix_forks(['fork':'start', F1, _, F2, Output, 'fork':'end'|T], I, ['control':'unpair','variable':V1,F1,Output,F2,'variable':V1,'control':'∧'|T2]) :- + atom_concat('Fork', I, V1), + J is I + 1, + fix_forks(T, J, T2). +fix_forks(['fork':'start', F1, _, F2, _, F3, Output, 'fork':'end'|T], I, ['control':'&',F1,'variable':V1,'control':'&',F3,'variable':V2,'control':'∧','variable':V1,'control':';','variable':V2,F2,Output|T2]) :- + atom_concat('Fork', I, V1), + J is I + 1, + atom_concat('Fork', J, V2), + K is I + 1, + fix_forks(T, K, T2). +fix_forks([H|T], I, [H|T2]) :- + dif(H, 'fork':'start'), + fix_forks(T, I, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + FIX_ARROWS +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +fix_arrows([], []). +fix_arrows(['predicate':P:_:Meta:Sup,'variable':_,'control':'↙','variable':V|T], T2) :- !, + ( atom(V) -> + V = VA + ; term_to_atom(V, VA) + ), + fix_arrows(['predicate':P:VA:Meta:Sup|T], T2). +fix_arrows(['predicate':P:Sub:Meta:_,'variable':_,'control':'↖','variable':V|T], T2) :- !, + ( atom(V) -> + V = VA + ; term_to_atom(V, VA) + ), + fix_arrows(['predicate':P:Sub:Meta:VA|T], T2). +fix_arrows(['predicate':P:_:Meta:Sup,'control':'↙','variable':V|T], T2) :- !, + ( atom(V) -> + V = VA + ; term_to_atom(V, VA) + ), + fix_arrows(['predicate':P:VA:Meta:Sup|T], T2). +fix_arrows(['predicate':P:Sub:Meta:_,'control':'↖','variable':V|T], T2) :- !, + ( atom(V) -> + V = VA + ; term_to_atom(V, VA) + ), + fix_arrows(['predicate':P:Sub:Meta:VA|T], T2). +fix_arrows([H|T], [H|T2]) :- + fix_arrows(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + TRANSPILE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +transpile(Program, [[':- style_check(-singleton).'], + [':- use_module(library(clpfd)).'], + [':- use_module(predicates).'], + [':- use_module(metapredicates).'], + [':- use_module(constraint_variables).\n'], + [MainPredHeader, + ConstraintVariables, + ' (1=1'|MainPred]|OtherPredicates], GlobalVariables) :- + atomic_list_concat(['brachylog_main(', + GlobalVariables, + ',_, Var_Input_Local,Var_Output_Local) :-\n', + ' Name = brachylog_main,\n', + ' GlobalVariables = ', + GlobalVariables,',\n', + ' nb_setval(\'declw\',[]),\n'], % Initialize declarative write variable + MainPredHeader), + constraint_variables(GlobalVariables, ConstraintVariables), + transpile_(Program, 'Var_Input_Local', no, no, 0, 0, [T|OtherPredicates], GlobalVariables), + reverse(T, [_|RT]), + reverse(RT, T2), + append(T2, ['\n', + ' ),\n', + ' (', + '(Var_Output_Local = integer:_ ; ', + 'Var_Output_Local = [_|_], ', + 'forall(member(E, Var_Output_Local), E = integer:_)) ', + '-> brachylog_label(default, Var_Output_Local, _) ', + '; true),\n', + ' nb_getval(\'declw\', DeclwFinal),\n', + ' maplist(write, DeclwFinal).'], % execute declarative write + MainPred). + +transpile_([], _, _, _, _, _, [['\n ).\n']], _). +transpile_(['variable':B|T], A, Reverse, Negate, AppendNumber, PredNumber, [[Unification|T2]|OtherPredicates], GlobalVariables) :- + A \= 'nothing', + ( is_list(A), + brachylog_list_to_atom(A, Var1) + ; A = Type:L, + term_to_atom(Type:L, Var1) + ; A = Var1 + ), + ( is_list(B), + brachylog_list_to_atom(B, Var2) + ; B = _:_, + term_to_atom(B, Var2) + ; Var2 = B + ), + ( Negate = yes, + UnificationAtom = ' \\= ' + ; Negate = no, + UnificationAtom = ' = ' + ), + ( Reverse = no, + atomic_list_concat([',\n ',Var2,UnificationAtom,Var1], Unification), + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) + ; Reverse = yes, + atomic_list_concat([',\n ',Var1,UnificationAtom,Var2], Unification), + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) + ). +transpile_(['variable':B|T], 'nothing', _, _, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['predicate':P:Sub:Meta:Sup,'variable':B|T], A, Reverse, Negate, AppendNumber, PredNumber, [[Predicate|T2]|OtherPredicates], GlobalVariables) :- + A \= 'nothing', + ( P = 'brachylog_call_predicate', + ( Sub = 'default' -> + RealSub = 'Name-GlobalVariables' + ; atomic_list_concat(['(',Sub,')-','GlobalVariables'], RealSub) + ) + ; P \= 'brachylog_call_predicate', + RealSub = Sub + ), + ( is_list(A), + brachylog_list_to_atom(A, Var1) + ; A = Type:L, + term_to_atom(Type:L, Var1) + ; A = Var1 + ), + ( is_list(B), + brachylog_list_to_atom(B, Var2) + ; B = _:_, + term_to_atom(B, Var2) + ; Var2 = B + ), + ( Negate = yes, + NegateAtom = '\\+ ' + ; Negate = no, + NegateAtom = '' + ), + ( Reverse = no -> + PredName = P + ; atomic_list_concat([P,'_reversed'], PredName) + ), + ( atomic_list_concat(['brachylog','predicate',_], '_', P) + -> atomic_list_concat([GlobalVariables,','], GlobVars) + ; GlobVars = '' + ), + ( Meta = no -> + atomic_list_concat([',\n ',NegateAtom,PredName,'(',GlobVars,RealSub,',',Var1,',',Var2,')'], Predicate) + ; ( atomic_list_concat(['brachylog','predicate',_], '_', P) + -> atomic_list_concat([GlobalVariables,','], GlobVarsMeta) + ; GlobVarsMeta = 'ignore,' + ), + atomic_list_concat([',\n ',NegateAtom,Meta,'(',GlobVarsMeta,Sup,',',PredName,',',RealSub,',',Var1,',',Var2,')'], Predicate) + ), + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'∧'|T], _, _, _, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + transpile_(T, 'nothing', no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'&'|T], _, _, _, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + transpile_(T, 'Var_Input_Local', no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'`'|T], B, _, _, AppendNumber, PredNumber, [['\n *->\n 1=1'|T2]|OtherPredicates], GlobalVariables) :- + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'∨'|T], _, _, _, AppendNumber, PredNumber, [['\n ;\n 1=1'|T2]|OtherPredicates], GlobalVariables) :- + transpile_(T, 'nothing', no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'('|T], B, _, Negate, AppendNumber, PredNumber, [[Parenthesis|T2]|OtherPredicates], GlobalVariables) :- + ( Negate = yes, + Parenthesis = ',\n \\+ (\n 1=1' + ; Negate = no, + Parenthesis = ',\n (\n 1=1' + ), + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':')'|T], B, _, _, AppendNumber, PredNumber, [['\n )'|T2]|OtherPredicates], GlobalVariables) :- + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'!'|T], B, _, _, AppendNumber, PredNumber, [[',\n !'|T2]|OtherPredicates], GlobalVariables) :- + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'⊥'|T], B, _, _, AppendNumber, PredNumber, [[',\n false'|T2]|OtherPredicates], GlobalVariables) :- + transpile_(T, B, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'~'|T], B, Reverse, Negate, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + ( Reverse = yes, + NewReverse = no + ; Reverse = no, + NewReverse = yes + ), + transpile_(T, B, NewReverse, Negate, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'¬'|T], B, Reverse, Negate, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + ( Negate = yes, + NewNegate = no + ; Negate = no, + NewNegate = yes + ), + transpile_(T, B, Reverse, NewNegate, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'unpair','variable':A|T], B, _, _, AppendNumber, PredNumber, [[Unpair|T2]|OtherPredicates], GlobalVariables) :- + ( A = TypeA:LA, + term_to_atom(TypeA:LA, TailElem) + ; A = TailElem + ), + ( B = TypeB:LB, + term_to_atom(TypeB:LB, Pair) + ; B = Pair + ), + atomic_list_concat(['UnpairTemp',AppendNumber],HeadElem), + atomic_list_concat([',\n ', + Pair,'=[',HeadElem,',',TailElem,']'],Unpair), + NewAppendNumber is AppendNumber + 1, + transpile_(T, HeadElem, no, no, NewAppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':';',Type:A|T], B, _, _, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables) :- + ( Type = 'variable' + ; Type = 'predicate' + ), + append([B], [A], NewVar), + transpile_(T, NewVar, no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':',','variable':A|T], B, _, _, AppendNumber, PredNumber, [[Append|T2]|OtherPredicates], GlobalVariables) :- + ( is_list(A), + brachylog_list_to_atom(A, Arg1) + ; A = TypeA:LA, + term_to_atom(TypeA:LA, Arg1) + ; A = Arg1 + ), + ( is_list(B), + brachylog_list_to_atom(B, Arg2) + ; B = TypeB:LB, + term_to_atom(TypeB:LB, Arg2) + ; B = Arg2 + ), + atomic_list_concat(['AppendTemp',AppendNumber],TempVar), + atomic_list_concat([',\n ', + '((',Arg2,' == [], \\+ is_brachylog_list(',Arg1,')) -> ',TempVar,' = [',Arg1,'] ; ', + 'brachylog_concatenate(default,', + '[',Arg2,',',Arg1,']', + ',',TempVar,') -> true ; is_brachylog_list(', + Arg2, + '), brachylog_concatenate(default,', + '[',Arg2,',[',Arg1,']]', + ',',TempVar,') -> true ; brachylog_concatenate(default,', + '[[',Arg2,'],[',Arg1,']],',TempVar,'))' + ], Append), + NewAppendNumber is AppendNumber + 1, + transpile_(T, TempVar, no, no, NewAppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'\n'|T], _, _, _, AppendNumber, PredNumber, [['\n ).\n'],[ReversedPred],[PredHead|T2]|OtherPredicates], GlobalVariables) :- + J is PredNumber + 1, + constraint_variables(GlobalVariables, ConstraintVariables), + atomic_list_concat(['brachylog_predicate_', + J, + '_reversed(', + GlobalVariables, + ',_, Input, Output', + ') :-\n', + ' brachylog_predicate_', + J, + '(', + GlobalVariables, + ',_, Output, Input', + ').\n'], ReversedPred), + atomic_list_concat(['brachylog_predicate_', + J, + '(', + GlobalVariables, + ',_, ', + 'Var_Input_Local', + ',Var_Output_Local', + ') :-\n Name = brachylog_predicate_', + J, + ',\n GlobalVariables = ', + GlobalVariables, + ',\n', + ConstraintVariables, + ' (1=1'], PredHead), + transpile_(T, 'Var_Input_Local', no, no, AppendNumber, J, [T2|OtherPredicates], GlobalVariables). +transpile_(['control':'|'|T], _, _, _, AppendNumber, PredNumber, [['\n ).\n'],[PredHead|T2]|OtherPredicates], GlobalVariables) :- + ( PredNumber = 0, + PredName = 'brachylog_main' + ; PredNumber \= 0, + atomic_list_concat(['brachylog_predicate_',PredNumber], PredName) + ), + constraint_variables(GlobalVariables, ConstraintVariables), + atomic_list_concat([PredName, + '(', + GlobalVariables, + ',_, ', + 'Var_Input_Local', + ',Var_Output_Local', + ') :-\n Name = ', + PredName, + ',\n GlobalVariables = ', + GlobalVariables, + ',\n', + ConstraintVariables, + ' (1=1'], PredHead), + transpile_(T, 'Var_Input_Local', no, no, AppendNumber, PredNumber, [T2|OtherPredicates], GlobalVariables). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + CONTAINS_WRITE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +contains_write(Code) :- + atom_chars(Code, SplittedCode), + tokenize(SplittedCode, Tokens), + fix_predicates(Tokens, FixedPredicates), + ( member(predicate:brachylog_write:_, FixedPredicates) + ; member(predicate:brachylog_writeln:_, FixedPredicates) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + CONSTRAINT_VARIABLES +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +constraint_variables(GlobalVariables, ConstraintVariables) :- + atom_chars(GlobalVariables, [_|Gs]), + reverse(Gs, [_|RGs]), + reverse(RGs, RRGs), + atomic_list_concat(RRGs, GGs), + atomic_list_concat(GlobVars, ',', GGs), + findall(S, (member(X, GlobVars), + atomic_list_concat(['Var', Name, _], '_', X), + atom_chars(Name, CName), + reverse(CName, [_,'t','n','i','a','r','t','s','n','o','C']), + constraint_variable(X, S)), Ss), + atomic_list_concat(Ss, GlobalConstraintVariables), + findall(T, (member(X, ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z']), + atomic_list_concat([' constraint',X,'(Var_Constraint',X,'_Local','),\n'], T)), + Ts + ), + atomic_list_concat(Ts, LocalConstraintVariables), + atomic_list_concat([GlobalConstraintVariables, LocalConstraintVariables], ConstraintVariables). + +constraint_variable(X, S) :- + atomic_list_concat(['Var', ConstraintName, _], '_', X), + atom_chars(ConstraintName, [C|Cs]), + downcase_atom(C, CDown), + atomic_list_concat([CDown|Cs], PredName), + atomic_list_concat([' ',PredName,'(',X,'),\n'], S). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_LIST_TO_ATOM +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_list_to_atom(List, Atom) :- + brachylog_list_to_atom_(List, T2), + atomic_list_concat(['[',T2,']'], Atom). + +brachylog_list_to_atom_([], ''). +brachylog_list_to_atom_([A], AtomA) :- + ( is_list(A), + brachylog_list_to_atom(A, AtomA) + ; A = _:_, + term_to_atom(A, AtomA) + ; \+ is_list(A), + A \= _:_, + AtomA = A + ). +brachylog_list_to_atom_([A,B|T], Atom) :- + ( is_list(A), + brachylog_list_to_atom(A, AtomA) + ; A = _:_, + term_to_atom(A, AtomA) + ; \+ is_list(A), + A \= _:_, + AtomA = A + ), + brachylog_list_to_atom_([B|T], T2), + atomic_list_concat([AtomA,',',T2], Atom). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + WRITE_TO_FILE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +write_to_file(File, []) :- + write(File, '\n\n'). +write_to_file(File, [H|T]) :- + write(File, H), + write_to_file(File, T). diff -r d054de7f80f2 -r 318de151d0ec ibin/brachylog/Brachylog-master/src/utils.pl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ibin/brachylog/Brachylog-master/src/utils.pl Tue Jul 16 21:37:27 2019 +0000 @@ -0,0 +1,195 @@ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +____ ____ +\ \ / / + \ \ ____ / / + \ \/ \/ / + \ /\ / BRACHYLOG + \ / \ / A terse declarative logic programming language + / \ / \ + / \/ \ Written by Julien Cumin - 2017 + / /\____/\ \ https://github.com/JCumin/Brachylog + / / ___ \ \ +/___/ /__/ \___\ + +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + +:- module(utils, [integer_value/2, + brachylog_prolog_variable/2, + length_/2, + prepend_string/2, + prepend_integer/2, + is_brachylog_list/1, + single_atom_code/2, + ceiled_square_root/2, + scompare/4, + if_/3, + (=)/3, + (#>)/3, + (===)/6 + ]). + +:- use_module(library(clpfd)). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + INTEGER_VALUE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +integer_value('integer':Sign:I, E) :- + integer_value('integer':Sign:I, 0, E, E). + +integer_value('integer':Sign:[], N0, N, _) :- + ( Sign = 'positive', + N #= N0 + ; Sign = 'negative', + N #= - N0 + ). +integer_value('integer':Sign:[H], N0, N, M) :- + H in 0..9, + N1 #= H + N0 * 10, + abs(M) #>= abs(N1), + integer_value('integer':Sign:[], N1, N, M). +integer_value('integer':Sign:[H,I|T], N0, N, M) :- + H in 0..9, + N1 #= H + N0 * 10, + abs(M) #>= abs(N1), + integer_value('integer':Sign:[I|T], N1, N, M). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + BRACHYLOG_PROLOG_VARIABLE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +brachylog_prolog_variable('integer':I, I) :- !. +brachylog_prolog_variable('float':F, F) :- !. +brachylog_prolog_variable('string':S, String) :- !, + escape_string_list(S, T), + atomic_list_concat(T, U), + atomic_list_concat(['"',U,'"'], A), + term_to_atom(String, A). +brachylog_prolog_variable(List, PrologList) :- + is_list(List), + maplist(brachylog_prolog_variable, List, PrologList). + +escape_string_list([], []). +escape_string_list(['"'|T], ['\\','"'|T2]) :- + escape_string_list(T, T2). +escape_string_list(['\\'|T], ['\\','\\'|T2]) :- + escape_string_list(T, T2). +escape_string_list([H|T], [H|T2]) :- + H \= '"', + H \= '\\', + escape_string_list(T, T2). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + LENGTH_ +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +length_(Length, List) :- + length(List, Length). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + PREPEND_STRING +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +prepend_string(S, 'string':S). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + PREPEND_INTEGER +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +prepend_integer(I, 'integer':I). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + IS_BRACHYLOG_LIST +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +is_brachylog_list([]). +is_brachylog_list([_|_]). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + SINGLE_ATOM_CODE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +single_atom_code(A, C) :- + catch(atom_codes(A, [C]), _, false). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + CEILED_SQUARE_ROOT +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +ceiled_square_root(0, 0). +ceiled_square_root(N0, Root) :- + N1 #= N0 - 1, + Max in 0..N1, + R0^2 #= Max, + Root #= Root0 + 1, + fd_sup(R0, Root0). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + SCOMPARE +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +scompare(@>, TypeX:X, TypeY:Y, TypeZ:Z) :- + ( X @> Y -> + TypeZ:Z = TypeX:X + ; TypeZ:Z = TypeY:Y + ). +scompare(@<, TypeX:X, TypeY:Y, TypeZ:Z) :- + ( X @< Y -> + TypeZ:Z = TypeX:X + ; TypeZ:Z = TypeY:Y + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + IF_/3 + Credits to Ulrich Neumerkel + See: http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/sicstus/reif.pl +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +if_(If_1, Then_0, Else_0) :- + call(If_1, T), + ( T == true -> Then_0 + ; T == false -> Else_0 + ; nonvar(T) -> throw(error(type_error(boolean,T), + type_error(call(If_1,T),2,boolean,T))) + ; throw(error(instantiation_error,instantiation_error(call(If_1,T),2))) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + (=)/3 + Credits to Ulrich Neumerkel + See: http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/sicstus/reif.pl +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +=(X, Y, T) :- + ( X == Y -> T = true + ; X \= Y -> T = false + ; T = true, X = Y + ; T = false, + dif(X, Y) + ). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + (#>)/3 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +#>(X, Y, T) :- + zcompare(C, X, Y), + greater_true(C, T). + +greater_true(>, true). +greater_true(<, false). +greater_true(=, false). + + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + (===)/6 +- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +===(X1, Y1, X2, Y2, T1, T) :- + ( X1 == Y1 -> T1 = true, T = true + ; X1 \= Y1 -> T1 = true, T = false + ; X2 == Y2 -> T1 = false, T = true + ; X2 \= Y2 -> T1 = false, T = false + ; T1 = true, T = true, X1 = Y1 + ; T1 = true, T = false, dif(X1, Y1) +).