Codebase list swi-prolog / 5922a21
New upstream version 8.1.30+dfsg Lev Lamberov 3 years ago
143 changed file(s) with 4844 addition(s) and 3133 deletion(s). Raw diff Collapse all Expand all
142142 set(INSTALL_TESTS_DIR ${SWIPL_INSTALL_PREFIX}/test)
143143 endif()
144144
145 if(NOT SWIPL_PKG_NAME)
146 if(SWIPL_INSTALL_DIR STREQUAL "swi-prolog")
147 set(SWIPL_PKG_NAME ${SWIPL_INSTALL_DIR})
148 else()
149 set(SWIPL_PKG_NAME "swipl")
150 endif()
151 endif()
152
145153 if(MSVC)
146154 add_compile_options(/W3)
147155 else()
0 8.1.29
0 8.1.30
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1985-2014, University of Amsterdam,
5 Copyright (c) 1985-2020, University of Amsterdam,
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
179180 ( Vars == v
180181 -> findall(Templ, Goal, List),
181182 List \== []
182 ; findall(Vars-Templ, Goal, Answers),
183 bind_bagof_keys(Answers,_),
183 ; alloc_bind_key_list(Vars, VDict),
184 findall(Vars-Templ, Goal, Answers),
185 bind_bagof_keys(Answers, VDict),
184186 keysort(Answers, Sorted),
185187 pick(Sorted, Vars, List)
186188 ).
189
190 %! alloc_bind_key_list(+Vars, -VDict) is det.
191 %
192 % Pre-allocate the variable dictionary used by bind_bagof_keys/2. By
193 % pre-allocating this list all variables bound become references from
194 % the `Vars` of each answer to this dictionary. If we do not
195 % preallocate we create a huge reference chain from VDict through each
196 % of the answers, causing serious slowdown in the subsequent keysort.
197 %
198 % The slowdown was discovered by Jan Burse.
199
200 alloc_bind_key_list(Vars, VDict) :-
201 functor(Vars, _, Count),
202 length(List, Count),
203 '$append'(List, _, VDict).
187204
188205 %! bind_bagof_keys(+VarsTemplPairs, -SharedVars)
189206 %
242259 -> findall(Templ, Goal, Answers),
243260 Answers \== [],
244261 sort(Answers, List)
245 ; findall(Vars-Templ, Goal, Answers),
262 ; alloc_bind_key_list(Vars, VDict),
263 findall(Vars-Templ, Goal, Answers),
246264 ( ground(Answers)
247 -> sort(Answers,Sorted),
248 pick(Sorted,Vars,List)
249 ; bind_bagof_keys(Answers,_VDict),
265 -> sort(Answers, Sorted),
266 pick(Sorted, Vars, List)
267 ; bind_bagof_keys(Answers, VDict),
250268 sort(Answers, Sorted),
251269 pick(Sorted, Vars, Listu),
252 sort(Listu,List) % Listu ordering may be nixed by Vars
270 sort(Listu, List) % Listu ordering may be nixed by Vars
253271 )
254272 ).
37603760 -> true
37613761 ; '$type_error'(callable, X)
37623762 ).
3763 '$must_be'(acyclic, X) :- !,
3764 ( acyclic_term(X)
3765 -> true
3766 ; '$domain_error'(acyclic_term, X)
3767 ).
37633768 '$must_be'(oneof(Type, Domain, List), X) :- !,
37643769 '$must_be'(Type, X),
37653770 ( memberchk(X, List)
5454
5555 start_tabling/3, % +Closure, +Wrapper, :Worker
5656 start_subsumptive_tabling/3,% +Closure, +Wrapper, :Worker
57 moded_start_tabling/5, % +Closure, +Wrapper, :Worker, :Variant, ?ModeArgs
57 start_abstract_tabling/3, % +Closure, +Wrapper, :Worker
58 start_moded_tabling/5, % +Closure, +Wrapper, :Worker,
59 % :Variant, ?ModeArgs
5860
5961 '$tbl_answer'/4, % +Trie, -Return, -ModeArgs, -Delay
6062
7375 not_exists(0),
7476 tabled_call(0),
7577 start_tabling(+, +, 0),
76 start_tabling(+, +, 0, +, ?),
78 start_abstract_tabling(+, +, 0),
79 start_moded_tabling(+, +, 0, +, ?),
7780 current_table(:, -),
7881 abolish_table_subgoals(:),
7982 '$wfs_call'(0, :).
270273 prolog_listen(untable, untable_reconsult).
271274
272275
273 %! start_tabling(:Wrapper, :Implementation)
274 %
275 % Execute Implementation using tabling. This predicate should not
276 % be called directly. The table/1 directive causes a predicate to
277 % be translated into a renamed implementation and a wrapper that
278 % involves this predicate.
279 %
280 % @compat This interface may change or disappear without notice
281 % from future versions.
282
283276 '$wrap_tabled'(Head, Options) :-
284277 get_dict(mode, Options, subsumptive),
285278 !,
286279 set_pattributes(Head, Options),
287280 '$wrap_predicate'(Head, table, Closure, Wrapped,
288281 start_subsumptive_tabling(Closure, Head, Wrapped)).
282 '$wrap_tabled'(Head, Options) :-
283 get_dict(subgoal_abstract, Options, _Abstract),
284 !,
285 set_pattributes(Head, Options),
286 '$wrap_predicate'(Head, table, Closure, Wrapped,
287 start_abstract_tabling(Closure, Head, Wrapped)).
289288 '$wrap_tabled'(Head, Options) :-
290289 !,
291290 set_pattributes(Head, Options),
310309 tabled_attribute(dynamic).
311310 tabled_attribute(tshared).
312311 tabled_attribute(max_answers).
313 tabled_attribute(abstract_subgoal).
312 tabled_attribute(subgoal_abstract).
314313 tabled_attribute(answer_abstract).
315314
315 %! start_tabling(:Closure, :Wrapper, :Implementation)
316 %
317 % Execute Implementation using tabling. This predicate should not be
318 % called directly. The table/1 directive causes a predicate to be
319 % translated into a renamed implementation and a wrapper that involves
320 % this predicate.
321 %
322 % @arg Closure is the wrapper closure to find the predicate quickly.
323 % It is also allowed to pass nothing. In that cases the predicate is
324 % looked up using Wrapper. We suggest to pass `0` in this case.
325 %
326 % @compat This interface may change or disappear without notice
327 % from future versions.
316328
317329 start_tabling(Closure, Wrapper, Worker) :-
318330 '$tbl_variant_table'(Closure, Wrapper, Trie, Status, Skeleton),
331 start_tabling_2(Closure, Wrapper, Worker, Trie, Status, Skeleton).
332
333 start_tabling_2(Closure, Wrapper, Worker, Trie, Status, Skeleton) :-
319334 tdebug(deadlock, 'Got table ~p, status ~p', [Trie, Status]),
320335 ( Status == complete
321336 -> trie_gen_compiled(Trie, Skeleton)
341356 tdebug(schedule, 'Leader ~p done, status = ~p', [Goal, LStatus]),
342357 done_leader(LStatus, Fresh, Skeleton, Clause).
343358
344
345359 %! restart_tabling(+Closure, +Wrapper, +Worker)
346360 %
347361 % We were aborted due to a deadlock. Simply retry. We sleep a very
356370 sleep(0.000001),
357371 start_tabling(Closure, Wrapper, Worker).
358372
359
360 %! start_subsumptive_tabling(:Wrapper, :Implementation)
373 restart_abstract_tabling(Closure, Wrapper, Worker) :-
374 tdebug(user_goal(Wrapper, Goal)),
375 tdebug(deadlock, 'Deadlock running ~p; retrying', [Goal]),
376 sleep(0.000001),
377 start_abstract_tabling(Closure, Wrapper, Worker).
378
379 %! start_subsumptive_tabling(:Closure, :Wrapper, :Implementation)
361380 %
362381 % (*) We should __not__ use trie_gen_compiled/2 here as this will
363382 % enumerate all answers while '$tbl_answer_update_dl'/2 uses the
403422 [GenSkeleton+Skeleton]).
404423
405424 unify_subsumptive(X,X).
425
426 %! start_abstract_tabling(:Closure, :Wrapper, :Worker)
427 %
428 % Deal with ``table p/1 as subgoal_abstract(N)``. This is a merge
429 % between variant and subsumptive tabling. If the goal is not
430 % abstracted this is simple variant tabling. If the goal is abstracted
431 % we must solve the more general goal and use answers from the
432 % abstract table.
433 %
434 % Wrapper is e.g., user:p(s(s(s(X))),Y)
435 % Worker is e.g., call(<closure>(p/2)(s(s(s(X))),Y))
436
437 start_abstract_tabling(Closure, Wrapper, Worker) :-
438 '$tbl_abstract_table'(Closure, Wrapper, Trie, _Abstract, Status, Skeleton),
439 tdebug(abstract, 'Wrapper=~p, Worker=~p, Skel=~p',
440 [Wrapper, Worker, Skeleton]),
441 ( is_most_general_term(Skeleton) % TBD: Fill and test Abstract
442 -> start_tabling_2(Closure, Wrapper, Worker, Trie, Status, Skeleton)
443 ; Status == complete
444 -> '$tbl_answer_update_dl'(Trie, Skeleton)
445 ; functor(Status, fresh, 2)
446 -> '$tbl_table_status'(Trie, _, GenWrapper, GenSkeleton),
447 abstract_worker(Worker, GenWrapper, GenWorker),
448 catch(create_abstract_table(Trie, Status, Skeleton, GenSkeleton, GenWrapper,
449 GenWorker),
450 deadlock,
451 restart_abstract_tabling(Closure, Wrapper, Worker))
452 ; Status == invalid
453 -> '$tbl_table_status'(Trie, _, GenWrapper, GenSkeleton),
454 reeval(ATrie, GenWrapper, GenSkeleton),
455 Wrapper = GenWrapper,
456 '$tbl_answer_update_dl'(ATrie, Skeleton)
457 ; shift(call_info(GenSkeleton, Skeleton, Status)),
458 unify_subsumptive(Skeleton, GenSkeleton)
459 ).
460
461 create_abstract_table(Trie, Fresh, Skeleton, GenSkeleton, Wrapper, Worker) :-
462 tdebug(Fresh = fresh(SCC, WorkList)),
463 tdebug(wl_goal(WorkList, Goal, _)),
464 tdebug(schedule, 'Created component ~d for ~p', [SCC, Goal]),
465 setup_call_catcher_cleanup(
466 '$idg_set_current'(OldCurrent, Trie),
467 run_leader(GenSkeleton, Worker, Fresh, LStatus, _Clause),
468 Catcher,
469 finished_leader(OldCurrent, Catcher, Fresh, Wrapper)),
470 tdebug(schedule, 'Leader ~p done, status = ~p', [Goal, LStatus]),
471 Skeleton = GenSkeleton,
472 done_abstract_leader(LStatus, Fresh, GenSkeleton, Trie).
473
474 abstract_worker(_:call(Term), _M:GenWrapper, call(GenTerm)) :-
475 functor(Term, Closure, _),
476 GenWrapper =.. [_|Args],
477 GenTerm =.. [Closure|Args].
478
479 :- '$hide'((done_abstract_leader/4)).
480
481 done_abstract_leader(complete, _Fresh, Skeleton, Trie) :-
482 !,
483 '$tbl_answer_update_dl'(Trie, Skeleton).
484 done_abstract_leader(final, fresh(SCC, _Worklist), Skeleton, Trie) :-
485 !,
486 '$tbl_free_component'(SCC),
487 '$tbl_answer_update_dl'(Trie, Skeleton).
488 done_abstract_leader(_,_,_,_).
489
490 %! done_leader(+Status, +Fresh, +Skeleton, -Clause)
491 %
492 % Called on completion of a table. Possibly destroys the component and
493 % generates the answers from the complete table. The last cases deals
494 % with leaders that are merged into a higher SCC (and thus no longer a
495 % leader).
406496
407497 :- '$hide'((done_leader/4, finished_leader/4)).
408498
506596 dependency(SrcSkeleton, Continuation, Skeleton, WorkList, AllDelays))
507597 ).
508598
509 %! moded_start_tabling(+Closure, :Wrapper, :Implementation, +Variant, +ModeArgs)
599 %! start_moded_tabling(+Closure, :Wrapper, :Implementation, +Variant, +ModeArgs)
510600 %
511601 % As start_tabling/2, but in addition separates the data stored in the
512602 % answer trie in the Variant and ModeArgs.
515605 '$set_predicate_attribute'(Head, tabled, true),
516606 '$wrap_predicate'(Head, table, Closure, Wrapped,
517607 ( ModeTest,
518 moded_start_tabling(Closure, Head, Wrapped,
608 start_moded_tabling(Closure, Head, Wrapped,
519609 WrapperNoModes, ModeArgs)
520610 )).
521611
522612
523 moded_start_tabling(Closure, Wrapper, Worker, WrapperNoModes, ModeArgs) :-
613 start_moded_tabling(Closure, Wrapper, Worker, WrapperNoModes, ModeArgs) :-
524614 '$tbl_moded_variant_table'(Closure, WrapperNoModes, Trie, Status, Skeleton),
525615 ( Status == complete
526616 -> moded_gen_answer(Trie, Skeleton, ModeArgs)
698788 %! tnot(:Goal)
699789 %
700790 % Tabled negation.
791 %
792 % (*): Only variant tabling is allowed under tnot/1.
701793
702794 tnot(Goal0) :-
703795 '$tnot_implementation'(Goal0, Goal), % verifies Goal is tabled
712804 ; negation_suspend(Goal, Skeleton, Status)
713805 )
714806 ; tdebug(tnot, 'tnot: ~p: fresh', [Goal]),
715 ( call(Goal),
807 ( '$wrapped_implementation'(Goal, table, Implementation), % see (*)
808 functor(Implementation, Closure, _),
809 start_tabling(Closure, Goal, Implementation),
716810 fail
717811 ; '$tbl_existing_variant_table'(_, Goal, Trie, NewStatus, NewSkeleton),
718812 tdebug(tnot, 'tnot: fresh ~p now ~p', [Goal, NewStatus]),
900994 abolish_table_subgoals(SubGoal0) :-
901995 '$tbl_implementation'(SubGoal0, M:SubGoal),
902996 !,
903 forall(( '$tbl_variant_table'(VariantTrie),
904 trie_gen(VariantTrie, M:SubGoal, Trie)
905 ),
906 '$tbl_destroy_table'(Trie)).
997 '$must_be'(acyclic, SubGoal),
998 ( '$tbl_variant_table'(VariantTrie),
999 trie_gen(VariantTrie, M:SubGoal, Trie),
1000 '$tbl_destroy_table'(Trie),
1001 fail
1002 ; true
1003 ).
9071004 abolish_table_subgoals(_).
9081005
9091006 %! abolish_module_tables(+Module) is det.
10141111 system:term_expansion/2.
10151112
10161113 wrappers(Spec, M) -->
1017 { tabling_defaults([ table_incremental-(incremental=true),
1018 table_shared-(tshared=true),
1019 table_subsumptive-((mode)=subsumptive)
1020 ],
1021 #{}, Defaults)
1114 { tabling_defaults(
1115 [ (table_incremental=true) - (incremental=true),
1116 (table_shared=true) - (tshared=true),
1117 (table_subsumptive=true) - ((mode)=subsumptive),
1118 call(subgoal_size_restraint(Level)) - (subgoal_abstract=Level)
1119 ],
1120 #{}, Defaults)
10221121 },
10231122 wrappers(Spec, M, Defaults).
10241123
11011200
11021201
11031202 tabling_defaults([], Dict, Dict).
1104 tabling_defaults([Flag-(Opt=Value)|T], Dict0, Dict) :-
1105 ( current_prolog_flag(Flag, true)
1203 tabling_defaults([Condition-(Opt=Value)|T], Dict0, Dict) :-
1204 ( tabling_default(Condition)
11061205 -> Dict1 = Dict0.put(Opt,Value)
11071206 ; Dict1 = Dict0
11081207 ),
11091208 tabling_defaults(T, Dict1, Dict).
11101209
1210 tabling_default(Flag=FValue) :-
1211 !,
1212 current_prolog_flag(Flag, FValue).
1213 tabling_default(call(Term)) :-
1214 call(Term).
1215
1216 % Called from wrappers//2.
1217
1218 subgoal_size_restraint(Level) :-
1219 current_prolog_flag(max_table_subgoal_size_action, abstract),
1220 current_prolog_flag(max_table_subgoal_size, Level).
11111221
11121222 %! table_options(+Options, +OptDictIn, -OptDictOut)
11131223 %
11441254 table_options(max_answers(Count), Opts0, Opts1) :-
11451255 !,
11461256 restraint(max_answers, Count, Opts0, Opts1).
1147 table_options(abstract_subgoal(Size), Opts0, Opts1) :-
1148 !,
1149 restraint(abstract_subgoal, Size, Opts0, Opts1).
1257 table_options(subgoal_abstract(Size), Opts0, Opts1) :-
1258 !,
1259 restraint(subgoal_abstract, Size, Opts0, Opts1).
11501260 table_options(answer_abstract(Size), Opts0, Opts1) :-
11511261 !,
11521262 restraint(answer_abstract, Size, Opts0, Opts1).
263263 endif()
264264 if(NOT MULTI_THREADED)
265265 swipl_del_package(swipl-win "requires multi-threading")
266 swipl_del_package(tipc "requires multi-threading")
266267 endif()
267268
268269 if(INSTALL_DOCUMENTATION)
177177 * MAPLIST/2... *
178178 *******************************/
179179
180 %! maplist(:Goal, ?List)
181 %
182 % True if Goal can successfully be applied on all elements of
183 % List. Arguments are reordered to gain performance as well as to
184 % make the predicate deterministic under normal circumstances.
180 %! maplist(:Goal, ?List1).
181 %! maplist(:Goal, ?List1, ?List2).
182 %! maplist(:Goal, ?List1, ?List2, ?List3).
183 %! maplist(:Goal, ?List1, ?List2, ?List3, ?List4).
184 %
185 % True if Goal is successfully applied on all matching elements of the
186 % list. The maplist family of predicates is defined as:
187 %
188 % ```
189 % maplist(P, [X11,...,X1n], ..., [Xm1,...,Xmn]) :-
190 % P(X11, ..., Xm1),
191 % ...
192 % P(X1n, ..., Xmn).
193 % ```
194 %
195 % This family of predicates is deterministic iff Goal is deterministic
196 % and List1 is a proper list, i.e., a list that ends in `[]`.
185197
186198 maplist(Goal, List) :-
187199 maplist_(List, Goal).
191203 call(Goal, Elem),
192204 maplist_(Tail, Goal).
193205
194 %! maplist(:Goal, ?List1, ?List2)
195 %
196 % As maplist/2, operating on pairs of elements from two lists.
197
198206 maplist(Goal, List1, List2) :-
199207 maplist_(List1, List2, Goal).
200208
203211 call(Goal, Elem1, Elem2),
204212 maplist_(Tail1, Tail2, Goal).
205213
206 %! maplist(:Goal, ?List1, ?List2, ?List3)
207 %
208 % As maplist/2, operating on triples of elements from three lists.
209
210214 maplist(Goal, List1, List2, List3) :-
211215 maplist_(List1, List2, List3, Goal).
212216
214218 maplist_([Elem1|Tail1], [Elem2|Tail2], [Elem3|Tail3], Goal) :-
215219 call(Goal, Elem1, Elem2, Elem3),
216220 maplist_(Tail1, Tail2, Tail3, Goal).
217
218
219 %! maplist(:Goal, ?List1, ?List2, ?List3, ?List4)
220 %
221 % As maplist/2, operating on quadruples of elements from four
222 % lists.
223221
224222 maplist(Goal, List1, List2, List3, List4) :-
225223 maplist_(List1, List2, List3, List4, Goal).
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2019, VU University Amsterdam
5 Copyright (c) 2019-2020, VU University Amsterdam
6 CWI, Amsterdam
67 All rights reserved.
78
89 Redistribution and use in source and binary forms, with or without
3637 trimcore/0,
3738
3839 abolish_table_info/0,
40 close_open_tables/1, % ?
3941
4042 str_cat/3,
4143
7880 % Undocumented in the XSB manual.
7981
8082 abolish_table_info.
83
84 %! close_open_tables(?Arg)
85 %
86 % Undocumented in the XSB manual. Tables are always closed on
87 % exceptions, so it is unclear what this should do?
88
89 close_open_tables(_).
8190
8291 %! str_cat(+Atom1, +Atom2, -Atom3)
8392
3333 */
3434
3535 :- module(xsb_source, []).
36 :- autoload(library(apply),[convlist/3,partition/4]).
37 :- autoload(library(debug),[debug/3]).
38 :- autoload(library(error),[instantiation_error/1]).
39 :- autoload(library(lists),[append/3,flatten/2]).
40
36 :- autoload(library(apply), [convlist/3,partition/4]).
37 :- autoload(library(debug), [debug/3]).
38 :- autoload(library(error), [instantiation_error/1]).
39 :- autoload(library(occurs), [sub_term/2]).
4140
4241 /** <module> Support XSB source .P files
4342
6665 file_name_extension(Path, 'P', File),
6766 include_options(File, Include),
6867 compiler_options(COptions),
69 append(Include, COptions, Extra),
68 '$append'(Include, COptions, Extra),
7069 xsb_directives(File, Directives),
7170 directive_exports(Directives, Public, Directives1),
7271 ( Public == []
8079 (:- use_module(library(tables)))
8180 | Out2
8281 ],
83 append(Extra, More, Out2),
82 '$append'(Extra, More, Out2),
8483 ( nonvar(Module)
8584 -> setup_call_cleanup(
8685 '$set_source_module'(OldM, Module),
87 convlist(head_directive(File), Directives1, More0),
86 phrase(head_directives(Directives1, File), More),
8887 '$set_source_module'(OldM))
89 ; convlist(head_directive(File), Directives1, More0)
88 ; phrase(head_directives(Directives1, File), More)
9089 ),
91 flatten(More0, More),
9290 debug(xsb(header), '~p: directives: ~p', [File, More]).
9391
9492 include_options(File, Option) :-
141139 export_decl(PI) -->
142140 [PI].
143141
144 %! head_directive(+File, +Directive, -PrefixedDirective) is semidet.
145
146 head_directive(File, import(from(Preds, From)),
147 (:- xsb_import(Preds, From))) :-
148 assertz(xsb:moved_directive(File, import(from(Preds, From)))).
149 head_directive(File, table(Preds as XSBOptions), Clauses) :-
150 ignored_table_options(XSBOptions, Options),
151 ( Options == true
152 -> expand_term((:- table(Preds)), Clauses)
153 ; expand_term((:- table(Preds as Options)), Clauses)
154 ),
155 assertz(xsb:moved_directive(File, table(Preds as XSBOptions))).
156 head_directive(File, table(Preds), Clauses) :-
157 expand_term((:- table(Preds)), Clauses),
158 assertz(xsb:moved_directive(File, table(Preds))).
142 %! head_directives(+Directives, +File)// is det.
143 %! head_directives_s(+Directives, +State)// is det.
144
145 head_directives(Directives, File) -->
146 { current_prolog_flag(max_table_subgoal_size_action, Action),
147 ( current_prolog_flag(max_table_subgoal_size, Size)
148 -> true
149 ; Size = -1
150 )
151 },
152 head_directives_s(Directives,
153 #{file: File,
154 max_table_subgoal_size_action: Action,
155 max_table_subgoal_size:Size
156 }).
157
158
159 head_directives_s([], _) --> [].
160 head_directives_s([H|T], State0) -->
161 { update_state(H, State0, State) },
162 !,
163 head_directives_s(T, State).
164 head_directives_s([H|T], State) -->
165 head_directive(H, State),
166 head_directives_s(T, State).
167
168 update_state(set_prolog_flag(max_table_subgoal_size_action, Action),
169 State0, State) :-
170 State = State0.put(max_table_subgoal_size_action, Action).
171 update_state(set_prolog_flag(max_table_subgoal_size, Size),
172 State0, State) :-
173 State = State0.put(max_table_subgoal_size, Size).
174
175 %! head_directive(+Directive, +State)// is det.
176
177 head_directive(import(from(Preds, From)), State) -->
178 !,
179 { assertz(xsb:moved_directive(State.file, import(from(Preds, From))))
180 },
181 [ (:- xsb_import(Preds, From)) ].
182 head_directive(table(Preds as XSBOptions), State) -->
183 !,
184 { ignored_table_options(XSBOptions, Options),
185 table_clauses(Preds, Options, Clauses, State),
186 assertz(xsb:moved_directive(State.file, table(Preds as XSBOptions)))
187 },
188 seq(Clauses).
189 head_directive(table(Preds), State) -->
190 !,
191 { table_clauses(Preds, true, Clauses, State),
192 assertz(xsb:moved_directive(State.file, table(Preds)))
193 },
194 seq(Clauses).
195 head_directive(_, _) -->
196 [].
197
198 seq([]) --> [].
199 seq([H|T]) --> [H], seq(T).
159200
160201 ignored_table_options((A0,B0), Conj) :-
161202 !,
176217 supported_table_option(shared).
177218 supported_table_option(private).
178219 supported_table_option(max_answers(_)).
179 supported_table_option(abstract_subgoal(_)).
220 supported_table_option(subgoal_abstract(_)).
180221 supported_table_option(answer_abstract(_)).
181222
182223 mkconj(true, X, X) :- !.
183224 mkconj(X, true, X) :- !.
184225 mkconj(X, Y, (X,Y)) :- !.
226
227 table_clauses(Preds, Options0, Clauses, State) :-
228 add_defaults(Options0, Options, State),
229 ( Options == true
230 -> expand_term((:- table(Preds)), Clauses)
231 ; expand_term((:- table(Preds as Options)), Clauses)
232 ).
233
234 add_defaults(Opts, Opts, _) :-
235 sub_term(subgoal_abstract(_), Opts),
236 !.
237 add_defaults(Opts0, Opts, State) :-
238 #{max_table_subgoal_size_action:abstract,
239 max_table_subgoal_size:Size} :< State,
240 Size >= 0,
241 !,
242 mkconj(Opts0, subgoal_abstract(Size), Opts).
243 add_defaults(Opts, Opts, _).
185244
186245 %! xsb_directives(+File, -Directives) is semidet.
187246 %
268268 comma_list(tnot(M:G), M) -->
269269 !,
270270 [tnot(G)].
271 comma_list(system:G, _) -->
272 !,
273 [G].
271274 comma_list(G, _) -->
272275 [G].
273276
104104
105105 '$timed_call_nested'(Goal, M:Options) :-
106106 memberchk(max(MaxInterval, MaxHandler), Options),
107 !,
107108 run_max_goal(Goal, MaxInterval, MaxHandler, M:Options).
108109 '$timed_call_nested'(Goal, M:Options) :-
109110 memberchk(repeating(RepInterval, RepHandler), Options),
4646 compiler_options/1, % +Options
4747
4848 xsb_import/2, % +Preds, From
49 xsb_set_prolog_flag/2, % +Flag, +Value
4950
5051 fail_if/1, % :Goal
5152
178179
179180 xsb_mapped_predicate(expand_file_name(File, Expanded),
180181 xsb_expand_file_name(File, Expanded)).
182 xsb_mapped_predicate(set_prolog_flag(Flag, Value),
183 xsb_set_prolog_flag(Flag, Value)).
181184 xsb_mapped_predicate(abolish_module_tables(UserMod),
182185 abolish_module_tables(user)) :-
183186 UserMod == usermod.
311314 !.
312315 map_module(XSB, Module) :-
313316 assertz(mapped__module(XSB, Module)).
317
318
319 %! xsb_set_prolog_flag(+Flag, +Value)
320 %
321 % Map some XSB Prolog flags to their SWI-Prolog's equivalents.
322
323 xsb_set_prolog_flag(unify_with_occurs_check, XSBVal) :-
324 !,
325 map_bool(XSBVal, Val),
326 set_prolog_flag(occurs_check, Val).
327 xsb_set_prolog_flag(Flag, Value) :-
328 set_prolog_flag(Flag, Value).
329
330 map_bool(on, true).
331 map_bool(off, false).
314332
315333
316334 /*******************************
167167 help_html(Matches, How, HTML) :-
168168 phrase(html(html([ head([]),
169169 body([ \match_type(How),
170 \man_pages(Matches,
171 [ no_manual(fail),
172 links(false),
173 link_source(false),
174 navtree(false),
175 server(false)
176 ])
170 dl(\man_pages(Matches,
171 [ no_manual(fail),
172 links(false),
173 link_source(false),
174 navtree(false),
175 server(false)
176 ]))
177177 ])
178178 ])),
179179 Tokens),
5151 :- autoload(library(option),[option/2,option/3,meta_options/3]).
5252 :- autoload(library(prolog_clause),[clause_info/5]).
5353
54 :- set_prolog_flag(generate_debug_info, false).
54 %:- set_prolog_flag(generate_debug_info, false).
5555
5656 :- module_transparent
5757 listing/0.
662662 portray_body(Body, BodyIndent, indent, RightPri, Out, Options)
663663 ),
664664 full_stop(Out).
665 do_portray_clause(Out, (:-use_module(File, Imports)), Options) :-
666 length(Imports, Len),
667 Len > 3,
668 !,
665 do_portray_clause(Out, (:-Directive), Options) :-
666 wrapped_list_directive(Directive),
667 !,
668 Directive =.. [Name, Arg, List],
669669 option(indent(LeftMargin), Options, 0),
670670 indent(Out, LeftMargin),
671 ListIndent is LeftMargin+14,
672 format(Out, ':- use_module(~q,', [File]),
673 portray_list(Imports, ListIndent, Out, Options),
674 write(Out, ').\n').
675 do_portray_clause(Out, (:-module(Module, Exports)), Options) :-
676 !,
677 option(indent(LeftMargin), Options, 0),
678 indent(Out, LeftMargin),
679 ModuleIndent is LeftMargin+10,
680 format(Out, ':- module(~q,', [Module]),
681 portray_list(Exports, ModuleIndent, Out, Options),
671 format(Out, ':- ~q(', [Name]),
672 line_position(Out, Indent),
673 format(Out, '~q,', [Arg]),
674 nlindent(Out, Indent),
675 portray_list(List, Indent, Out, Options),
682676 write(Out, ').\n').
683677 do_portray_clause(Out, (:-Directive), Options) :-
684678 !,
701695 '$put_token'(Out, '.'),
702696 nl(Out).
703697
698 wrapped_list_directive(module(_,_)).
699 %wrapped_list_directive(use_module(_,_)).
700 %wrapped_list_directive(autoload(_,_)).
704701
705702 %! portray_body(+Term, +Indent, +DoIndent, +Priority, +Out, +Options)
706703 %
958955 !,
959956 write(Out, []).
960957 portray_list(List, Indent, Out, Options) :-
961 nlindent(Out, Indent),
962958 write(Out, '[ '),
963959 EIndent is Indent + 2,
964960 portray_list_elements(List, EIndent, Out, Options),
19581958 valid_decl_option(Option, Which),
19591959 !,
19601960 functor(Option, Name, _),
1961 colour_item(decl_option(Name), TB, Pos),
1962 ( Pos = term_position(_,_,_,_,[ArgPos])
1963 -> ( arg(1, Option, Value),
1961 ( Pos = term_position(_,_,FF,FT,[ArgPos])
1962 -> colour_item(decl_option(Name), TB, FF-FT),
1963 ( arg(1, Option, Value),
19641964 nonneg_or_false(Value)
19651965 -> colourise_term_arg(Value, TB, ArgPos)
19661966 ; colour_item(type_error(decl_option_value(Which)), TB, ArgPos)
19671967 )
1968 ; true
1968 ; colour_item(decl_option(Name), TB, Pos)
19691969 ).
19701970 colourise_decl_options(_, Which, TB, Pos) :-
19711971 colour_item(type_error(decl_option(Which)), TB, Pos).
0 /* Part of SWI-Prolog
1
2 Author: Jan Wielemaker
3 E-mail: J.Wielemaker@vu.nl
4 WWW: http://www.swi-prolog.org
5 Copyright (c) 2020, VU University Amsterdam
6 CWI, Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 :- module(prolog_deps,
36 [ file_autoload_directives/3, % +File, -Directives, +Options
37 file_auto_import/2 % +File, +Options
38 ]).
39 :- use_module(library(apply), [convlist/3, maplist/3]).
40 :- use_module(library(filesex), [copy_file/2]).
41 :- use_module(library(lists), [select/3, subtract/3, append/3, member/2]).
42 :- use_module(library(option), [option/2, option/3]).
43 :- use_module(library(pairs), [group_pairs_by_key/2]).
44 :- use_module(library(pprint), [print_term/2]).
45 :- use_module(library(prolog_code), [pi_head/2]).
46 :- use_module(library(prolog_source),
47 [ file_name_on_path/2,
48 path_segments_atom/2,
49 prolog_open_source/2,
50 prolog_read_source_term/4,
51 prolog_close_source/1
52 ]).
53 :- use_module(library(prolog_xref),
54 [ xref_source/1,
55 xref_module/2,
56 xref_called/4,
57 xref_defined/3,
58 xref_built_in/1
59 ]).
60 :- use_module(library(readutil), [read_file_to_string/3]).
61 :- use_module(library(solution_sequences), [distinct/2]).
62
63 /** <module> Compute file dependencies
64
65 This module computes file dependencies for _modules_ as a set of
66 directives.
67 */
68
69
70 %! file_autoload_directives(+File, -Directives, +Options) is det.
71 %
72 % Compute the dependencies as autoload/2 directives. Options
73 %
74 % - missing(+Bool)
75 % If `true` (default `false`), only generate directives
76 % for called predicates that are not already imported.
77 %
78 % - directive(+Directive)
79 % Directive to use for adding dependencies. Defined
80 % options are:
81 %
82 % - use_autoload/2
83 % (Default). This uses use_module/2 for files that
84 % cannot be imported using use_autoload/2.
85 % - use_autoload/1
86 % This uses use_module/1 for files that cannot be
87 % imported using use_autoload/1.
88 % - use_module/2
89 % - use_module/1
90 %
91 % - update(Old)
92 % Updated an existing set of directives. The returned
93 % set of Directive starts with copies of Old. If a
94 % member of Old is autoload/2 or use_module/2, new
95 % dependencies are added at the end of this list.
96 % New dependent files are added after the modified
97 % copies of Old. Declared dependencies are never
98 % removed, even if no proof of usage is found.
99 %
100 % If no directive(+Directive) option is provided a
101 % default is determined from the given directives.
102
103 file_autoload_directives(File, Directives, Options) :-
104 xref_source(File),
105 findall(Head, distinct(Head, undefined(File, Head, Options)), Missing),
106 convlist(missing_autoload(File), Missing, Pairs),
107 keysort(Pairs, Pairs1),
108 group_pairs_by_key(Pairs1, Grouped),
109 directives(Grouped, Directives, Options).
110
111 %! undefined(+File, -Callable, +Options)
112 %
113 % Callable is called in File, but no definition can be found. If
114 % File is not a module file we consider other files that are not
115 % module files.
116
117 undefined(File, Undef, Options) :-
118 xref_module(File, _),
119 !,
120 xref_called_cond(File, Undef, Cond),
121 \+ ( available(File, Undef, How, Options),
122 How \== plain_file
123 ),
124 included_if_defined(Cond, Undef),
125 Undef \= (_:_).
126 undefined(File, Undef, Options) :-
127 xref_called_cond(File, Undef, Cond),
128 \+ available(File, Undef, _, Options),
129 included_if_defined(Cond, Undef),
130 Undef \= (_:_).
131
132 %! included_if_defined(+Condition, +Callable) is semidet.
133
134 included_if_defined(true, _) :- !.
135 included_if_defined(false, _) :- !, fail.
136 included_if_defined(fail, _) :- !, fail.
137 included_if_defined(current_predicate(Name/Arity), Callable) :-
138 \+ functor(Callable, Name, Arity),
139 !.
140 included_if_defined(\+ Cond, Callable) :-
141 !,
142 \+ included_if_defined(Cond, Callable).
143 included_if_defined((A,B), Callable) :-
144 !,
145 included_if_defined(A, Callable),
146 included_if_defined(B, Callable).
147 included_if_defined((A;B), Callable) :-
148 !,
149 ( included_if_defined(A, Callable)
150 ; included_if_defined(B, Callable)
151 ).
152
153 xref_called_cond(Source, Callable, Cond) :-
154 xref_called(Source, Callable, By, Cond),
155 By \= Callable. % recursive calls
156
157 %! available(+File, +Callable, -HowDefined, +Options)
158 %
159 % True if Callable is available in File.
160
161 available(File, Called, How, Options) :-
162 xref_defined(File, Called, How0),
163 ( How0 = imported(_)
164 -> option(missing(true), Options)
165 ; true
166 ),
167 !,
168 How = How0.
169 available(_, Called, How, _) :-
170 built_in_predicate(Called),
171 !,
172 How = builtin.
173 available(_, Called, How, _) :-
174 Called = _:_,
175 defined(_, Called),
176 !,
177 How = module_qualified.
178 available(_, M:G, How, _) :-
179 defined(ExportFile, G),
180 xref_module(ExportFile, M),
181 !,
182 How = module_overruled.
183 available(_, Called, How, _) :-
184 defined(ExportFile, Called),
185 \+ xref_module(ExportFile, _),
186 !,
187 How == plain_file.
188
189 %! built_in_predicate(+Callable)
190 %
191 % True if Callable is a built-in
192
193 built_in_predicate(Goal) :-
194 strip_module(Goal, _, Plain),
195 xref_built_in(Plain).
196
197 %! defined(?File, ?Callable)
198 %
199 % True if Callable is defined in File and not imported.
200
201 defined(File, Callable) :-
202 xref_defined(File, Callable, How),
203 How \= imported(_).
204
205
206 /*******************************
207 * GENERATE OUTPUT *
208 *******************************/
209
210 missing_autoload(_Src, Head, File-Head) :-
211 predicate_property(Head, autoload(File)),
212 !.
213 missing_autoload(Src, Head, From-Head) :-
214 xref_defined(Src, Head, imported(From)),
215 !.
216 missing_autoload(_Src, Head, _) :-
217 pi_head(PI, Head),
218 print_message(warning,
219 error(existence_error(procedure, PI), _)),
220 fail.
221
222 %! directives(+FileAndHeads, -Directives, +Options) is det.
223 %
224 % Assemble the final set of directives. Uses the option update(Old).
225
226 directives(FileAndHeads, Directives, Options) :-
227 option(update(Old), Options, []),
228 phrase(update_directives(Old, FileAndHeads, RestDeps), Directives, Rest),
229 update_style(Old, Options, Options1),
230 maplist(directive(Options1), RestDeps, Rest0),
231 sort(Rest0, Rest).
232
233 update_directives([], Deps, Deps) -->
234 [].
235 update_directives([:-(H)|T], Deps0, Deps) -->
236 { update_directive(H, Deps0, Deps1, Directive) },
237 !,
238 [ :-(Directive) ],
239 update_directives(T, Deps1, Deps).
240 update_directives([H|T], Deps0, Deps) -->
241 [ H ],
242 update_directives(T, Deps0, Deps).
243
244 update_directive(Dir0, Deps0, Deps, Dir) :-
245 directive_file(Dir0, FileSpec),
246 absolute_file_name(FileSpec, File,
247 [ file_type(prolog),
248 file_errors(fail),
249 access(read)
250 ]),
251 select(DepFile-Heads, Deps0, Deps),
252 same_dep_file(DepFile, File),
253 !,
254 ( Dir0 =.. [Pred,File,Imports]
255 -> maplist(pi_head, PIs, Heads),
256 subtract(PIs, Imports, New),
257 append(Imports, New, NewImports),
258 Dir =.. [Pred,File,NewImports]
259 ; Dir = Dir0
260 ).
261
262 directive_file(use_module(File), File).
263 directive_file(use_module(File,_), File).
264 directive_file(autoload(File), File).
265 directive_file(autoload(File,_), File).
266
267 same_dep_file(File, File) :-
268 !.
269 same_dep_file(Dep, _File) :-
270 exists_file(Dep),
271 !,
272 fail.
273 same_dep_file(Dep, File) :-
274 user:prolog_file_type(Ext, prolog),
275 file_name_extension(Dep, Ext, DepFile),
276 same_file(DepFile, File),
277 !.
278
279
280 %! update_style(+OldDirectives, +Options0, -Options)
281 %
282 % Determine the directive to use for new dependencies. This
283 % establishes a default based on existing dependencies.
284
285 update_style(_Old, Options, Options) :-
286 option(directive(_), Options),
287 !.
288 update_style(Old, Options, [directive(autoload/2)|Options]) :-
289 memberchk((:- autoload(_,_)), Old),
290 !.
291 update_style(Old, Options, [directive(autoload/1)|Options]) :-
292 memberchk((:- autoload(_)), Old),
293 !.
294 update_style(Old, Options, [directive(use_module/2)|Options]) :-
295 memberchk((:- use_module(_,_)), Old),
296 !.
297 update_style(Old, Options, [directive(use_module/1)|Options]) :-
298 memberchk((:- use_module(_)), Old),
299 !.
300 update_style(_, Options, Options).
301
302
303 %! directive(+Options, +FileAndHeads, -Directive)
304 %
305 % Create a directive to import Heads from File.
306
307 directive(Options, File-Heads, Directive) :-
308 file_name_extension(File, pl, LibFile),
309 file_name_on_path(LibFile, Lib0),
310 segments(Lib0, Lib),
311 maplist(pi_head, PIs, Heads),
312 make_directive(Lib, PIs, Directive, Options).
313
314 segments(Term0, Term) :-
315 Term0 =.. [Alias,Atom],
316 path_segments_atom(Segments, Atom),
317 format(atom(Atom), '~q', [Segments]),
318 !,
319 Term =.. [Alias,Segments].
320 segments(FilePL, File) :-
321 atom(FilePL),
322 file_name_extension(File, pl, FilePL),
323 !.
324 segments(Term, Term).
325
326 :- multifile
327 prolog:no_autoload_module/1.
328
329 make_directive(Lib, Import, (:- use_module(Lib, Import)), Options) :-
330 option(directive(use_module/2), Options, use_autoload/2),
331 !.
332 make_directive(Lib, _Import, (:- use_module(Lib)), Options) :-
333 option(directive(use_module/1), Options, use_autoload/2),
334 !.
335 make_directive(Lib, _Import, (:- use_module(Lib)), Options) :-
336 option(directive(use_autoload/1), Options, use_autoload/2),
337 prolog:no_autoload_module(Lib),
338 !.
339 make_directive(Lib, Import, (:- use_module(Lib, Import)), _) :-
340 prolog:no_autoload_module(Lib),
341 !.
342 make_directive(Lib, _Import, (:- autoload(Lib)), Options) :-
343 option(directive(use_autoload/1), Options, use_autoload/2),
344 !.
345 make_directive(Lib, Import, (:- autoload(Lib, Import)), _).
346
347
348 /*******************************
349 * REPLACE *
350 *******************************/
351
352 %! file_auto_import(+File, +Options)
353 %
354 % Update the autoload/2 directives for File. This predicate __modifies
355 % the file in place__. Defined options are:
356 %
357 % - backup(+Extension)
358 % Create a backup of File using Extension.
359
360 file_auto_import(File, Options) :-
361 absolute_file_name(File, Path,
362 [ file_type(prolog),
363 access(read)
364 ]),
365 file_autoload_directives(Path, Directives, Options),
366 ( option(backup(Ext), Options)
367 -> file_name_extension(Path, Ext, Old),
368 copy_file(Path, Old)
369 ; true
370 ),
371 Edit = _{import:Directives, done:_},
372 ( has_import(Path)
373 -> edit_file(Old, Path, Edit.put(replace,true))
374 ; edit_file(Old, Path, Edit.put(new,true))
375 ).
376
377 has_import(InFile) :-
378 setup_call_cleanup(
379 prolog_open_source(InFile, In),
380 ( repeat,
381 prolog_read_source_term(In, Term, _Expanded, []),
382 ( Term == end_of_file
383 -> !
384 ; true
385 )
386 ),
387 prolog_close_source(In)),
388 nonvar(Term),
389 import_directive(Term),
390 !.
391
392 import_directive((:- use_module(_))).
393 import_directive((:- use_module(_, _))).
394
395 %! rewrite_term(+In, -Keep, -OutList, +Options) is semidet.
396
397 rewrite_term(Never,_,_,_) :-
398 never_rewrite(Never),
399 !,
400 fail.
401 rewrite_term(Import,false,[],Options) :-
402 Options.done == true,
403 !,
404 import_directive(Import).
405 rewrite_term(In,false,Directives,Options) :-
406 import_directive(In),
407 !,
408 append(Options.import, [nl], Directives),
409 Options.done = true.
410 rewrite_term(In,true,Directives,Options) :-
411 In = (:- module(_,_)),
412 Options.get(new) == true,
413 !,
414 append(Options.import, [nl], Directives),
415 Options.done = true.
416
417 never_rewrite((:- use_module(_, []))).
418
419 edit_file(InFile, OutFile, Options) :-
420 read_file_to_string(InFile, String, []),
421 setup_call_cleanup(
422 prolog_open_source(InFile, In),
423 setup_call_cleanup(
424 open(OutFile, write, Out),
425 rewrite(In, Out, String, Options),
426 close(Out)),
427 prolog_close_source(In)).
428
429 rewrite(In, Out, String, Options) :-
430 prolog_read_source_term(
431 In, Term, _Expanded,
432 [ term_position(StartPos),
433 subterm_positions(TermPos),
434 comments(Comments)
435 ]),
436 stream_position_data(char_count, StartPos, StartChar),
437 copy_comments(Comments, StartChar, String, Out),
438 ( Term == end_of_file
439 -> true
440 ; ( nonvar(Term),
441 rewrite_term(Term, Keep, List, Options)
442 -> ( Keep == true
443 -> copy_term_string(TermPos, String, Out)
444 ; true
445 ),
446 forall(member(T, List),
447 output_term(Out, T)),
448 ( append(_, [nl], List)
449 -> skip_blanks(In)
450 ; true
451 )
452 ; copy_term_string(TermPos, String, Out)
453 ),
454 rewrite(In, Out, String, Options)
455 ).
456
457 output_term(Out, nl) :-
458 !,
459 nl(Out).
460 output_term(Out, Term) :-
461 print_term(Term, [output(Out)]),
462 format(Out, '.~n', []).
463
464 copy_comments([Pos-H|T], StartChar, String, Out) :-
465 stream_position_data(char_count, Pos, Start),
466 Start < StartChar,
467 !,
468 string_length(H, Len),
469 sub_string(String, Start, Len, _, Comment),
470 End is Start+Len+1,
471 layout_after(End, String, Layout),
472 format(Out, '~s~s', [Comment, Layout]),
473 copy_comments(T, StartChar, String, Out).
474 copy_comments(_, _, _, _).
475
476 copy_term_string(TermPos, String, Out) :-
477 arg(1, TermPos, Start),
478 arg(2, TermPos, End),
479 Len is End - Start,
480 sub_string(String, Start, Len, _, TermString),
481 End1 is End + 1,
482 full_stop_after(End1, String, Layout),
483 format(Out, '~s~s', [TermString, Layout]).
484
485 layout_after(Index, String, [H|T]) :-
486 string_code(Index, String, H),
487 code_type(H, space),
488 !,
489 Index2 is Index+1,
490 layout_after(Index2, String, T).
491 layout_after(_, _, []).
492
493 full_stop_after(Index, String, [H|T]) :-
494 string_code(Index, String, H),
495 Index2 is Index+1,
496 ( code_type(H, space)
497 -> !, full_stop_after(Index2, String, T)
498 ; H == 0'.
499 -> !, layout_after(Index2, String, T)
500 ).
501 full_stop_after(_, _, []).
502
503 skip_blanks(In) :-
504 peek_code(In, C),
505 code_type(C, space),
506 !,
507 get_code(In, _),
508 skip_blanks(In).
509 skip_blanks(_).
562562 safe_primitive(copy_term(_,_)).
563563 safe_primitive(system:duplicate_term(_,_)).
564564 safe_primitive(system:copy_term_nat(_,_)).
565 safe_primitive(system:size_abstract_term(_,_,_)).
565566 safe_primitive(numbervars(_,_,_)).
566567 safe_primitive(system:numbervars(_,_,_,_)).
567568 safe_primitive(subsumes_term(_,_)).
12341235 % tabling
12351236 safe_prolog_flag(max_answers_for_subgoal,_).
12361237 safe_prolog_flag(max_answers_for_subgoal_action,_).
1238 safe_prolog_flag(max_table_answer_size,_).
1239 safe_prolog_flag(max_table_answer_size_action,_).
1240 safe_prolog_flag(max_table_subgoal_size,_).
1241 safe_prolog_flag(max_table_subgoal_size_action,_).
12371242
12381243
12391244 %! prolog:sandbox_allowed_expansion(:G) is det.
270270
271271 %! order_by(+Spec, :Goal)
272272 %
273 % Order solutions according to Spec. Spec is a list of terms,
274 % where each element is one of. The ordering of solutions of Goal
275 % that only differ in variables that are _not_ shared with Spec is
276 % not changed.
273 % Order solutions according to Spec. Spec is a list of terms, where
274 % each element is one of. The ordering of solutions of Goal that only
275 % differ in variables that are _not_ shared with Spec is not changed.
277276 %
278277 % - asc(Term)
279278 % Order solution according to ascending Term
280279 % - desc(Term)
281280 % Order solution according to descending Term
281 %
282 % This predicate is based on findall/3 and (thus) variables in answers
283 % are _copied_.
282284
283285 order_by(Spec, Goal) :-
284286 must_be(list, Spec),
778778 Returns non-zero if \arg{term} is a compound term using the list
779779 constructor. See also PL_is_list() and PL_skip_list().
780780
781 \cfunction{int}{PL_is_dict}{term_t}
782 Returns non-zero if \arg{term} is a dict. See also PL_put_dict()
783 and PL_get_dict_key().
784
781785 \cfunction{int}{PL_is_atomic}{term_t}
782786 Returns non-zero if \arg{term} is atomic (not a variable or compound).
783787
964968 If \arg{t} is an atom, the system will look up or create the
965969 corresponding module and assign an opaque pointer to it over {\em
966970 module}.
971
967972 \cfunction{int}{PL_get_arg}{size_t index, term_t +t, term_t -a}
968973 If \arg{t} is compound and index is between 1 and arity (inclusive),
969974 assign \arg{a} with a term reference to the argument.
975
970976 \cfunction{int}{_PL_get_arg}{size_t index, term_t +t, term_t -a}
971977 Same as PL_get_arg(), but no checking is performed, neither whether \arg{t}
972978 is actually a term nor whether \arg{index} is a valid argument index.
979
980 \cfunction{int}{PL_get_dict_key}{atom_t key, term_t +dict, term_t -value}
981 If \arg{dict} is a dict, get the associated value in \arg{value}. Fails
982 silently if \arg{key} does not appear in \arg{dict} and with an
983 exception if \arg{dict} is not a dict.
973984 \end{description}
974985
975986
13431354 Note that \arg{l} can be redefined within a {\tt PL_cons_list} call as
13441355 shown here because operationally its old value is consumed before its
13451356 new value is set.
1357
1358 \cfunction{int}{PL_put_dict}{term_t -h, atom_t tag, size_t len,
1359 const atom_t *keys, term_t values}
1360 Create a dict from a \arg{tag} and vector of atom-value pairs and put
1361 the result in \arg{h}. The dict's key is set by \arg{tag}, which may
1362 be \const{0} to leave the tag unbound. The \arg{keys} vector is a vector
1363 of atoms of at least \arg{len} long. The \arg{values} is a term vector
1364 allocated using PL_new_term_refs() of at least \arg{len} long. This
1365 function returns \const{TRUE} on success, \const{FALSE} on a resource
1366 error (leaving a resource error exception in the environment),
1367 \const{-1} if some key or the \arg{tag} is invalid and \const{-2} if
1368 there are duplicate keys.
13461369 \end{description}
13471370
13481371
29042927 mp_set_memory_functions() in the GMP documentation. The action returns
29052928 \const{FALSE} if there is no GMP support or GMP is already initialised.
29062929 \end{description}
2930
2931 \cfunction{unsigned int}{PL_version}{int key}
2932 Query version information. This function may be called before
2933 PL_initialise(). If the key is unknown the function returns 0.
2934 See \secref{abi-versions} for a more in-depth discussion on
2935 binary compatibility. Defined keys are:
2936
2937 \begin{description}
2938 \termitem{PL_VERSION_SYSTEM}{}
2939 SWI-Prolog version as $10,000 \times major + 100 \times minor + patch$.
2940 \termitem{PL_VERSION_FLI}{}
2941 Incremented if the foreign interface defined in this chapter changes in
2942 a way that breaks backward compatibility.
2943 \termitem{PL_VERSION_REC}{}
2944 Incremented if the binary representation of terms as used by
2945 PL_record_external() and fast_write/2 changes.
2946 \termitem{PL_VERSION_QLF}{}
2947 Incremented if the QLF file format changes.
2948 \termitem{PL_VERSION_QLF_LOAD}{}
2949 Represents the oldest loadable QLF file format version.
2950 \termitem{PL_VERSION_VM}{}
2951 A hash that represents the VM instructions and their arguments.
2952 \termitem{PL_VERSION_BUILT_IN}{}
2953 A hash that represents the names, arities and properties of all
2954 built-in predicates defined in C. If this function is called
2955 before PL_initialise() it returns 0.
2956 \end{description}
29072957 \end{description}
29082958
29092959 \subsection{Querying Prolog}
5858
5959 \newcommand{\vmajor}{8}
6060 \newcommand{\vminor}{1}
61 \newcommand{\vpatch}{29}
61 \newcommand{\vpatch}{30}
6262 \newcommand{\vtag}{}
63 \newcommand{\vmonth}{April}
63 \newcommand{\vmonth}{May}
6464 \newcommand{\vyear}{2020}
6565
6666 #ifdef BOOK
350350 \cmdlineoptionitem{--version}{}
351351 When given as the only option, it summarises the version and the
352352 architecture identifier. Also available as \cmdlineoption{-v}.
353
354 \cmdlineoptionitem{--abi_version}{}
355 Print a key (string) that represents the binary compatibility on
356 a number of aspects. See \secref{abi-versions}.
353357 \end{description}
354358
355359
11811185
11821186
11831187 \begin{description}
1188 \prologflagitem{abi_version}{dict}{r}
1189 The flag value is a dict with keys that describe the version of
1190 the various Application Binary Interface (ABI) components. See
1191 \secref{abi-versions} for details.
1192
11841193 \prologflagitem{access_level}{atom}{rw}
11851194 This flag defines a normal `user' view (\const{user}, default) or a
11861195 `system' view. In system view all system code is fully accessible as if
35013510 start with a dollar (\chr{\$}) sign.
35023511
35033512 \input{bit64.tex}
3513
3514 \section{Binary compatibility} \label{sec:abi-versions}
3515
3516 \index{compatibility,binary}%
3517 \index{ABI,compatibility}%
3518 SWI-Prolog first of all attempts to maintain \jargon{source code}
3519 compatibility between versions. Data and programs can often be
3520 represented in binary form. This touches a number of interfaces
3521 with varying degrees of compatibility. The relevant version numbers
3522 and signatures are made available by PL_version(), the
3523 \cmdlineoption{abi_version} and the Prolog flag
3524 \prologflag{abi_version}.
3525
3526 \begin{description}
3527 \definition{Foreign extensions}
3528 Dynamically loadable foreign extensions have the usual dependencies on
3529 the architecture, ABI model of the (C) compiler, dynamic link library
3530 format, etc. They also depend on the backward compatibility of the PL_*
3531 API functions provided lib \file{libswipl}.
3532
3533 A compatible API allows distribution of foreign extensions in binary
3534 form, notably for platforms on which compilation is complicated (e.g.,
3535 Windows). This compatibility is therefore high on the priority list, but
3536 must infrequently be compromised.
3537
3538 PL_version(): \const{PL_VERSION_FLI}, \prologflag{abi_version} key:
3539 \const{foreign_interface}
3540
3541 \definition{Binary terms}
3542 Terms may be represented in binary format using PL_record_external() and
3543 fast_write/2. As these formats are used for storing binary terms in
3544 databases or communicate terms between Prolog processes in binary form,
3545 great care is taken to maintain compatibility.
3546
3547 PL_version(): \const{PL_VERSION_REC}, \prologflag{abi_version} key:
3548 \const{record}
3549
3550 \definition{QLF files}
3551 QLF files (see qcompile/1) are binary representation of Prolog file or
3552 module. They represent clauses as sequences of \jargon{virtual machine}
3553 (VM) instructions. Their compatibility relies on the QLF file format and
3554 the ABI of the VM. Some care is taken to maintain compatibility.
3555
3556 PL_version(): \const{PL_VERSION_QLF}, \const{PL_VERSION_QLF_LOAD} and
3557 \const{PL_VERSION_VM}, \prologflag{abi_version} key: \const{qlf},
3558 \const{qlf_min_load}, \const{vmi}
3559
3560 \definition{Saved states}
3561 Saved states (see \cmdlineoption{-c} and qsave_program/2) is a zip file
3562 that contains the entire Prolog database using the same representation
3563 as QLF files. A saved state may contain additional resources, such as
3564 foreign extensions, data files, etc. In addition to the dependency
3565 concerns of QLF files, built-in and core library predicates may call
3566 \emph{internal} foreign predicates. The interface between the public
3567 built-ins and internal foreign predicates changes frequently. Patch
3568 level releases in the \emph{stable branch} will as much as possible
3569 maintain compatibility.
3570
3571 The relevant ABI version keys are the same as for QLF files with one
3572 addition: PL_version(): \const{PL_VERSION_BUILT_IN}, \prologflag{abi_version}
3573 key: \const{built_in}
3574 \end{description}
3575
839839 \subsection{Restraint subgoal size}
840840 \label{sec:tabling-restraint-subgoal}
841841
842 Using the \term{abstract_subgoal}{Size} attribute, a tabled subgoal that
842 Using the \term{subgoal_abstract}{Size} attribute, a tabled subgoal that
843843 that is too large is \jargon{abstracted} by replacing compound subterms
844844 of the goal with variables. In a nutshell, a goal
845845 \term{p}{s(s(s(s(s(0)))))} is converted into the semantically equivalent
916916
917917
918918 /** uri_query_components(+QueryString, -ValueList) is det.
919
920 (*) We must malloc() because the individual query components use the
921 text ring buffer, so with more query components then the ring size the
922 original text gets corrupted.
919923 */
920924
921925 static foreign_t
923927 { pl_wchar_t *s;
924928 size_t len;
925929
926 if ( PL_get_wchars(string, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST) )
927 { return unify_query_string_components(list, len, s);
930 if ( PL_get_wchars(string, &len, &s, CVT_ATOM|CVT_STRING|CVT_LIST|BUF_MALLOC) )
931 { int rc = unify_query_string_components(list, len, s);
932 PL_free(s); /* See (*) */
933 return rc;
928934 } else if ( PL_is_list(list) )
929935 { term_t tail = PL_copy_term_ref(list);
930936 term_t head = PL_new_term_ref();
1010 ${JQUERYFILE}
1111 PATHS /usr/share/javascript/jquery
1212 NO_DEFAULT_PATH)
13 # Deal with snap creation
14 string(REPLACE "-sdk/current/" "/current/" JQUERYDIR "${JQUERYDIR}")
1315 endif()
1416
1517 if(JQUERYDIR AND EXISTS ${JQUERYDIR}/${JQUERYFILE})
00 cmake_minimum_required(VERSION 3.5)
11 project(swipl-jpl)
22
3 set(JPL_VERSION 7.6.0)
34
45 #message(${CMAKE_CURRENT_SOURCE_DIR}) # <project>/packages/jpl
56 #message(${PROJECT_SOURCE_DIR}) # <project>/packages/jpl
00 # Deploying for users - on Linux
11
2 Recall that to use JPL under linux one must have the following in place:
2 To use JPL under Linux one must have the following in place (here showing the locations under Linux Mint distribution under packages `swi-prolog-nox` and `swi-prolog-java`):
33
4 * C Native JPL Library `libjpl.so`, generally found at `/usr/lib/swi-prolog/lib/amd64/libjpl.so`
5 * Java API Jar file `jpl.jar` in the Java `CLASSPATH`, generally accessible from `/usr/share/java/jpl.jar`.
6 * Prolog API as an SWI source module `jpl.pl` at `$SWI_HOME_DIR/library`, generally accessible from `/usr/lib/swi-prolog/library/jpl.pl`
7
8 JPL is **generally distributed with official Linux**. For example, in Ubuntu-based systems, JPL is provided via package `swi-prolog-java`. That package includes the C library `libjpl.so`, the Java API `jpl.jar`, the Prolog module `jpl.pl` as well as all documentation associated.
4 * A SWIPL install containing the core SWI system, which includes:
5 * A SWIPL home directory (`SWI_HOME_DIR`), located at `/usr/lib/swi-prolog/` and containing the whole SWIPL core system, including a booting `.prc` file (`$SWI_HOME_DIR/boot64.prc`).
6 * The "home" of SWIPL can be queried via [`current_prolog_flag(home, H)`](https://www.swi-prolog.org/pldoc/man?predicate=current_prolog_flag/2)
7 * The C Native core SWIPL library `/usr/lib/libswipl.so`.
8 * The set of C Native SWIPL libraries for each package (files `.so`), located in `/usr/lib/swi-prolog/lib/amd64/`
9 * The JPL package, which includes:
10 * The C Native JPL Library `libjpl.so` at `$SWI_HOME_DIR/lib/amd64/libjpl.so`.
11 * The Java API JAR file `jpl.jar` in `$SWI_HOME_DIR/lib/jpl.jar`.
12 * The Prolog API as an SWIPL source module `jpl.pl` at `$SWI_HOME_DIR/library`.
13
14 ## Which SWIPL version to (not) use?
15
16 JPL is **generally distributed with official Linux**. For example, in Ubuntu-based systems, JPL is provided via package `swi-prolog-java`. That package includes the C library `libjpl.so`, the Java API `jpl.jar`, the Prolog module `jpl.pl` as well as all associated documentation.
917
1018 However, the **official packages are often out-of-date**. For Debian-based systems (Debian, Ubuntu, Mint, ...) you can get the latest stable and development versions via [this PPAs](http://www.swi-prolog.org/build/PPA.txt) provided directly by SWI-Prolog.
1119
12 To use JPL, use either SWI stable version 7.6.4 (available in standard Linux repos) or compile and install 8.1.x from SWI-devel repo.
13 * **Note:** The official stable SWI 8.0.x versions (as of Jan 2020) have issues with the `libswipl.so/dll/dylib` library and makes JPL crash; see [issue](https://github.com/ssardina-research/packages-jpl/issues/21). It has been fixed in the git repo but will only show up with versions 8.1.x.
20 Use either SWIPL stable version 7.6.4 (available in standard Linux repos) or compile & install 8.1.x from [SWI-devel repo](https://github.com/SWI-Prolog/swipl-devel) using CMAKE.
21 * **Note:** The official stable SWI 8.0.x versions (as of Jan 2020) have issues with the `libswipl.so/dll/dylib` library and makes JPL crash; see [issue](https://github.com/ssardina-research/packages-jpl/issues/21). It has been fixed in the git repo but will only show up with versions 8.1.x.
22
23 ## Configuring environment variables
1424
15 Finally, to be **able to use JPL** you may need to make sure that:
25 When embeeding SWIPL into a Java, one may needs to "tell" the Java application the right information, via environment variables, so that SWIPL is initialized properly and can find all resources.
1626
17 * Extend environment library `LD_PRELOAD` for system to pre-load `libswipl.so`:
18 * `export LD_PRELOAD=libswipl.so:$LD_PRELOAD`
19 * Check [this post](https://answers.ros.org/question/132411/unable-to-load-existing-owl-in-semantic-map-editor/) and [this one](https://blog.cryptomilk.org/2014/07/21/what-is-preloading/) about library preloading.
20 * Also, check [this](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=690734) and [this](https://github.com/yuce/pyswip/issues/10) posts.
21 * Extend environment variable `LD_LIBRARY_PATH` to point to the directory where `libjpl.so` is located:
22 * `export LD_LIBRARY_PATH=/usr/lib/swi-prolog/lib/amd64/`
23 * Make sure `jpl.jar` is in your Java CLASSPATH. This is generally automatically done if environment variable `SWI_HOME_DIR` is correctly set to `/usr/lib/swi-prolog/`.
27 In general, if the Java application will use the default executable of the system (i.e., the one that runs when executing `swipl`), then you only need to set-up `CLASSPATH` to include `jpl.jar` and possibly `LD_PRELOAD` to point to your active SWIPL `libswipl.so` library to avoid run-time errors. The executable has a pointer to the right information to initialize; see [here](https://www.swi-prolog.org/FAQ/FindResources.html).
2428
25 To install JPL from scratch (e.g., to compiling it in order to develop it further) please refer to the [Developing JPL](Developing-JPL) guide.
29 However, if your Java application will use an SWIPL & JPL version that is _not_ the exectuable default.
30
31 ### Using stable distribution versions of SWIPL
32
33 If the **Linux distribution install** of SWIPL & JPL is not the executable default but the one to be used, set-up the following environment variables:
34
35 SWI_HOME_DIR=/usr/lib/swi-prolog/ # if default binary not pointing to this version
36 LD_LIBRARY_PATH=/usr/lib/swi-prolog/lib/amd64/ # to find all .so, including libjpl.so
37 CLASSPATH=/usr/lib/swi-prolog/lib/jpl.jar
38 LD_PRELOAD=/usr/lib/libswipl.so # see below for explanation
39
40 or in one line (for IDE Run configurations, for example):
41
42 CLASSPATH=/usr/lib/swi-prolog/lib/jpl.jar;LD_LIBRARY_PATH=/usr/lib/swi-prolog/lib/amd64/;LD_PRELOAD=/usr/lib/libswipl.so;SWI_HOME_DIR=/usr/lib/swi-prolog/
43
44 Notice that, in this case, library `libswipl.so` will be found automatically, as it is located in the standard system-wide library dir `/usr/lib`.
45
46 ### Using locally compiled and installed version of SWIPL
47
48 Alternatively, if you have **compiled and installed** an SWIPL system, say, under directory `/usr/local/swipl-git/`, then the SWIPL home will be `/usr/local/swipl-git/lib/swipl/`, the executable binary will be `/usr/local/swipl-git/lib/swipl/bin/x86_64-linux/swipl` and the environment variables should be set-up as follows:
49
50 SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/ # if binary exec not pointing to this SWIPL
51 LD_LIBRARY_PATH=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/ # to find all .so, including libjpl.so
52 CLASSPATH=/usr/local/swipl-git/lib/swipl/lib/jpl.jar
53 LD_PRELOAD=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/libswipl.so # see below for explanation
54
55 or in one line (for IDE Run configurations, for example):
56
57 CLASSPATH=/usr/local/swipl-git/lib/swipl/lib/jpl.jar;LD_LIBRARY_PATH=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/;LD_PRELOAD=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/libswipl.so;SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/
58
59 ## Using the development tree of SWI+JPL that is yet not installed?
60
61 If you want to run your application against a development tree of SWIPL & JPL that is not yet installed, then refer to [Developing JPL](TutorialDeveloping.md) guide.
62
2663
2764 ## Troubleshooting
65
66 ### Pre-loading `libswipl.so`
67
68 The [libray preloading](https://blog.cryptomilk.org/2014/07/21/what-is-preloading/) of `libswipl.so` is often necessary to avoid the following run-time error (check [this](https://answers.ros.org/question/132411/unable-to-load-existing-owl-in-semantic-map-editor/), [this](https://github.com/yuce/pyswip/issues/10) and [this](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=690734) posts):
69
70 ERROR: /usr/lib/swi-prolog/library/process.pl:53:
71 /usr/lib/swi-prolog/library/process.pl:53: Initialization goal raised exception:
72 '$open_shared_object'/3: /usr/lib/swi-prolog/lib/amd64/process.so: undefined symbol: Sfilefunctions
73
74 ### [FATAL ERROR: Could not find system resources].
75
76 It is not finding the correct `libswipl.so`.
9797
9898 `Term` instances are never changed by any activity within the Prolog engine: indeed; it doesn't know of their existence.
9999
100 The `Term` class is abstract, so it cannot be directly instantiated; to create a Term, create an instance of one of its subclasses.
100 The `Term` class is abstract, so it cannot be directly instantiated; to create a Term, create an instance of one of its subclasses, which are the ones accounting for the various [data types in SWI-Prolog](https://www.swi-prolog.org/datatypes.html).
101101
102102 ### Atoms
103103
234234 public Term arg0(int i);
235235 ```
236236
237 #### Lists as compound terms
238
239 As usual in Prolog, lists are just compound terms with function `[|]` and two arguments: the _head_ element and the _tail_ list. For example:
240
241 ```prolog
242 ?- A = [1,2,3,4], A =.. [X|Y].
243 A = [1, 2, 3, 4],
244 X = '[|]',
245 Y = [1, [2, 3, 4]].
246 ````
247
248 We can build list compound terms in two ways. First, by converting an Array of terms (`Term[]`) into a Compound (list) term using utility `Util.termArrayToList`:
249
250 ```java
251 Term list = Util.termArrayToList(new Term[]
252 { new Integer(1), new Variable("B"), new Atom("c") });
237 ### Lists
238
239 In SWI-Prolog a list is either:
240
241 * An empty list `[]`. In JPL, the empty list is the constant `JPL.LIST_NIL` and is a final object of class `Atom`. (Observe on the SWI side, from SWI-Prolog 7+, the empty list is not an atom but a reserved word.)
242 * A `Compound` term with functor `[|]` and two arguments where the second one is itself a list. On the Prolog side:
243
244 ?- A = [1,2,3,4], A =.. [X|Y].
245 A = [1, 2, 3, 4],
246 X = '[|]',
247 Y = [1, [2, 3, 4]].
248
249 While one can build non-empty lists by creating `Compound` terms, it can become really cumbersome, as the second argument always has to be another lits.
250
251 So, class `Term` provides several _static_ methods to conveniently build non-empty lists, namely:
252
253 ```java
254 public static Term textToTerm(String text)
255 public static Term termArrayToList(Term[] terms)
256 public static Term stringArrayToList(String[] a)
257 public static Term intArrayToList(int[] a)
258 public static Term intArrayArrayToList(int[][] a)
259 ```
260
261 Method `textToTerm(String text)` can actually build _any_ term form its String representation, including list terms:
262
263 ```java
264 Term list = Util.textToTerm("[1, B, [p(g), g(1)], c]");
265 ```
266
267 A second tool is `termArrayToList(Term[])`, which builds a list from an Array of Terms (`Term[]`) (the corresponding functors `[|]` are added automatically). For example:
268
269 ```java
270 Term list = Term.termArrayToList(new Term[] // list [1, B, hello]
271 { new Integer(1), new Variable("B"), new Atom("hello") });
253272 ```
254273
255 The second way is by converting a String representing a list into a term via `Util.textToTerm`:
256
257 ```java
258 Term list = Util.textToTerm("[1, B, c]");
259 ```
260
274 Finally, one can build specific data-type lists using:
275 * `stringArrayToList(String[] a)`: builds a list of atoms from an Array of Strings;
276 * `intArrayToList(int[] a)`: builds a list of integers;
277 * `intArrayArrayToList(int[][] a)`: builds a list of lists of integers.
278
279 On the other direction, the following methods in `Term` class transform a list Term into another Java type:
280
281 ```java
282 public static String toString(Term t)
283 public static Term[] listToTermArray(Term t)
284 public static String[] atomListToStringArray(Term t)
285 ```
286
287 When it comes to non-empty, compound, list terms, the behavior of `toString()` will depend on boolean `JPL.LIST_TOSTRING_TEXTUAL`:
288 * If True, lists will be represented as String in the usual Prolog textual representation `[e1, e2, e3, ...., en]`. Note a space wil be added after each comma always.
289 * If False, lists will be represented in infix notation with the list pair functor `[|]`, e.g., `[|](1, [|](2, [|](3, '[]')))` for list `[1, 2, 3]`.
261290
262291
263292
347376 ```
348377
349378 If the query has no solutions, this method returns `null`; otherwise, a non-null return indicates success. If the query is ground (i.e. contains no variables), the returned map will be empty (i.e. will contain no bindings).
379
380 If the query is non-ground (i.e., it includes variables), then bindings are retrieved by name, e.g.:
381
382 ```
383 Map m = org.jpl7.Query.oneSolution("statistics(heap, X)");
384 long heapsize = m.get("X");
385 ```
386
350387
351388 ### Obtaining all solutions
352389
456493
457494 ## Gotchas
458495
459 ### Variables are named
460
461 Instances of `org.jpl7.Variable` have names, and bindings are retrieved by name, e.g.
462
463 ```
464 Map m = org.jpl7.Query.oneSolution("statistics(heap, X)");
465 long heapsize = m.get("X");
466 ```
467
468496 ### Argument numbering
469497
470498 The `Term[]` args of a `Compound` are indexed (like all Java arrays) from zero, whereas in Prolog the args of a structure are conventionally numbered from one.
33
44 * Version [JPL 7.x](https://jpl7.org/) uses SWI Prolog V7 and has modernise JPL's APIs significantly.
55
6 * Current version []7.4.0](https://jpl7.org/ReleaseNotes740.jsp) works with SWI versions V7.4.x to V7.7.x. It has a new implemention of JRefs as blobs to address Java objects from Prolog.
6 * Version [7.6.0](https://jpl7.org/ReleaseNotes760.jsp) works with SWI versions V8.1.x+. It adds Rationals as a data type and has several term methods refactored into class Term.
7
8 * Version [7.5.0](https://jpl7.org/ReleaseNotes750.jsp) works with SWI versions V7.4.x to V7.7.x. It has a new implemention of iterators ans solution methods in Queries and better handling of quoted terms.
9
10 * Version [7.4.0](https://jpl7.org/ReleaseNotes740.jsp) works with SWI versions V7.4.x to V7.7.x. It has a new implemention of JRefs as blobs to address Java objects from Prolog.
711
812 * Versions [JPL 3.x,y](http://www.swi-prolog.org/packages/jpl/) implemented many changes and worked with SWI V5.2.0 or later (it used multi-threading FLI calls not available in older versions) and Java 2 runtime. It was tested with Microsoft Visual C/C++ 5 under Windows NT 4.0 (SP6a).
913
1414 ## Versions up to 7.4
1515
1616 - Complete overhawl from version 3.x
17 - Check release notes for [7.4.0](https://jpl7.org/ReleaseNotes740.jsp).
18 - Check release notes for [7.0.1](https://jpl7.org/ReleaseNotes701.jsp).
17 - Check release notes for [7.4.0](ReleaseNotes740).
18 - Check release notes for [7.0.1](ReleaseNotes701).
1919
2020
2121
0 # Release Notes - 7.6.0
1
2 - New `org.jpl7.Rational` type to handle [SWI rationals](https://www.swi-prolog.org/pldoc/man?section=rational).
3 - Refactored several methods dealing with JPL terms, from `org.jpl7.Util` to `org.jpl7.Term`:
4 - `Term textToTerm(String text)`
5 - `String[] atomListToStringArray(Term t)`
6 - `static Term intArrayArrayToList(int[][] a)`
7 - `Term intArrayToList(int[] a)`
8 - `boolean isList(Term term)`
9 - `int listToLength(Term term)`
10 - `Term[] listToTermArray(Term t)`
11 - `Term stringArrayToList(String[] a)`
12 - `Term termArrayToList(Term[] terms)`
13 - Added a textual mode for `Term.toString()` to convert non-empty lists in Prolog textual style `[e2, e2, ..., en]` instead of the pre-fix functor-based style `'[|]'(e1, '[|]'(e2, '[|]'(...,'[|]'(en,'[]')..)`.
14 - This textual mode is used when `JPL.LIST_TOSTRING_TEXTUAL` is True (default is True); otherwise default pre-fix style is used.
15 - Added specific section for lists in documentation.
16
17 ## Internal
18
19 - More direct and simpler `Term.textToTerm(String text)` without using
20 `getSolutionWithVarNames` and by renaming anonymous Variable terms to give them the textual name.
21 - Migrated unit testing from JUnit3 to JUnit4.
22 - Refactored the unit testing test suite; all test files subclass of `org.jpl7.java.test.junit.JPLTest`.
23 - Modified init arguments and CMAKE configuration for SWI embeded engine unit testing to fix issue with engine not loading libraries. No more use of `libswipl.dll` as first argument; all packages available in unit tetsing now.
24 - Added some static versions of instance methods in class `Term`.
177177 [ssardina@Thinkpad-X1 build]$
178178 ```
179179
180
181 ## Using non-installed development tree of SWIPL & JPL in Java application
182
183 Suppose you are developing JPL as above, in this case at `/home/ssardina/git/soft/prolog/swipl-devel.git`
184
185 However, you have a Java application X besides JPL itself and want to test that application under the current SWIPL+JPL development. There are several things that need to be set-up for your application to correctly access the SWIPL+JPL under development.
186
187 First, we need to **setup various environment variables** so that the correct SWIPL+JPL is initialized and used:
188
189 SWI_HOME_DIR=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home
190 SWI_EXEC_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/swipl
191 SWIPL_BOOT_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home/boot.prc
192 LD_LIBRARY_PATH=/home/ssardina/git/soft/prolog/swipl-devel.git/build/packages/jpl
193 LD_PRELOAD=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/libswipl.so
194 CLASSPATH=/home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/out/artifacts/jpl_jar/
195
196 The `CLASSPATH` needs to point to the `jpl.jar` file that needs to be us used in case `jpl.pl` requires it (to access JAVA from Prolog).
197
198 In one line (to copy into the usual Run-configuration of IDE):
199
200 LD_LIBRARY_PATH=/home/ssardina/git/soft/prolog/swipl-devel.git/build/packages/jpl;SWI_HOME_DIR=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home;SWIPL_BOOT_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home/boot.prc;CLASSPATH=/home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/out/artifacts/jpl_jar/;LD_PRELOAD=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/libswipl.so;SWI_EXEC_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/swipl
201
202
203 Second, we need to tell our applicatoin X development to use the development JPL Java, and NOT any other `jpl.jar` that may be in the system (e.g., due to a distribution installation). In our example, under IntelliJ, we define a library `jpl` in the project of the application pointing to directory:
204
205 /home/ssardina/git/soft/prolog/swipl-devel.git/packages/jpl/out/production/jpl
206
207 where all the classes for the currente devel JPL are located (if we are using IntelliJ). Then provded that library to use for your application/module for compilation and runtime.
208
209 Third, and finally, you need to explicitly initialize the SWIPL JPL engine in your Java application to with the right home, executable, and most importantly `-F swipl` so that the initialization file `swipl.rc` in charge of setting up all the search paths:
210
211 ```java
212 String init_swi_config =
213 String.format("%s -x %s -F swipl --home=%s -g true -q",
214 System.getenv("SWI_EXEC_FILE"), # irrelevant for Windows
215 System.getenv("SWIPL_BOOT_FILE"),
216 System.getenv("SWI_HOME_DIR"));
217 JPL.setDefaultInitArgs(init_swi_config.split("\\s+")); # initialize SWIPL engine
218 JPL.init()
219 ```
220
221 Because SWIPL tries to "guess" the location of the binary and boot file, in most cases, it also suffies to do:
222
223 ```java
224 String init_swi_config =
225 String.format("dummy --home=%s -g true -q",
226 System.getenv("SWI_HOME_DIR"));
227 JPL.setDefaultInitArgs(init_swi_config.split("\\s+")); # initialize SWIPL engine
228 ```
229
230
231
1313 You may wish to load this database into an interactive Prolog session to experiment with the predicates in this database before experimenting with JPL.
1414
1515
16 ## Initializing The Prolog engine
16 ## Initializing the Prolog engine
1717
18 Although the `org.jpl7.JPL` class provides a number of methods for initializing the Prolog engine from within Java, their use is not usually necessary: Prolog will be automatically initialised with default parameters at the first attempt to use it.
18 Although the `org.jpl7.JPL` class provides a number of methods for initializing the Prolog engine from within Java, their use is not usually necessary: Prolog will be _automatically initialised_ with default parameters at the first attempt to use it.
19
20 By default, the SWIPL install accessible via the _default executable_ (i.e., the one that runs when one types `swipl`) will be initialized. If one, instead, _requires to use another install_ of SWIPL+JPL (e.g., the one under development or an alternative one installed in `/usr/local`), then we need to set-up a few variables to make sure the intended SWIPL resources are found. For example, suppose we intend that our Java-based application uses the SWIPL framework locally installed in `/usr/local/swipl/`. Then:
21
22 SWI_HOME_DIR=/usr/local/swipl-git/lib/swipl/ # root of SWIPL install
23 LD_LIBRARY_PATH=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/ # all .so nativ libs
24 LD_PRELOAD=/usr/local/swipl-git/lib/swipl/lib/x86_64-linux/libswipl.so
25 CLASSPATH=/usr/local/swipl-git/lib/swipl/lib/jpl.jar
26
27 From here, [SWIPL will try to find/guess the resources](https://www.swi-prolog.org/FAQ/FindResources.html) and set-up the engine correctly.
28
29 Note also that you need to tell your development environment (e.g., IntelliJ or ECLIPSE) to use the correct `jpl.jar` (rather than one coming with the default active SWIPL system) or even the place where the JPL compiled classes are located if you intend to use a development (but uninstall) version of JPL.
30
31 Sometimes one needs to _explicitly initialize_ the engine (before a query triggers defaul initialization); for example, if one wants to use an SWIPL & JPL under a development tree that is not yet installed. Assuming that development is happening under `/home/ssardina/git/soft/prolog/swipl-devel.git`, the following code template will perform a comprehensive, and quiety, initialization (before any query is performed) (see [CLI options](https://www.swi-prolog.org/pldoc/man?section=cmdline) available):
32
33 ```java
34 String init_swi_config =
35 String.format("%s -x %s -F swipl --home=%s -g true -q",
36 System.getenv("SWI_EXEC_FILE"), # irrelevant for Windows
37 System.getenv("SWIPL_BOOT_FILE"),
38 System.getenv("SWI_HOME_DIR"));
39 JPL.setDefaultInitArgs(init_swi_config.split("\\s+")); # initialize SWIPL engine
40 JPL.init()
41 ```
42
43 The option `-F swipl` will cause the script `$SWI_HOME_DIR/swipl.rc` to be loaded which will set-up all the search paths relative to the install. The above code will require the following environment variables:
44
45 SWI_HOME_DIR=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home
46 SWI_EXEC_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/src/swipl
47 SWIPL_BOOT_FILE=/home/ssardina/git/soft/prolog/swipl-devel.git/build/home/boot.prc
48
49 Because SWIPL tries to "guess" the location of the binary and boot file, in most cases, it also suffies to do:
50
51 ```java
52 String init_swi_config =
53 String.format("dummy --home=%s -g true -q",
54 System.getenv("SWI_HOME_DIR"));
55 JPL.setDefaultInitArgs(init_swi_config.split("\\s+")); # initialize SWIPL engine
56 ```
1957
2058
2159
7171 // process solution...
7272 }
7373 while (query1.hasMoreSolutions()) { // finish processing query1
74 Map<String, Term> solution = query2.nextSolution();
74 Map<String, Term> solution = query1.nextSolution();
7575 // process solution...
7676 }
7777 ```
148148
149149 [Queries from multi-threaded applications](https://jpl7.org/JavaApiOverview#queries-from-multi-threaded-applications)
150150
151 as well in this related issue at Github: https://github.com/SWI-Prolog/packages-jpl/issues/15
151 as well in this related [issue #15](https://github.com/SWI-Prolog/packages-jpl/issues/15) at Github:
152152
153153
2121 * minimum impact deployability: runtime support for Prolog+Java apps must be a position-independent, self-sufficient filestore tree, requiring no changes to registries, system libraries, system configuration files etc;
2222 * minimum dependency deployability: as with JVMs, the Prolog+Java runtime support must depend upon nothing which cannot be taken for granted in healthy OS installations; and
2323 * minimum vulnerability deployability: the Prolog+Java runtime support must be immune to legitimate variations in its environment (PATH settings, other applications and libraries including other Prolog+Java apps, etc.).
24
25 ### Historical perspective
26
27 JPL was originally dreamed to be independent of Prolog implementation, mapping only the classic Prolog term model to and from Java, and its Java-side implementation deliberately resisted adoption of post Java 1.4 features (some nice, but none irresistible), thereby maintaining compatibility with (now very) old JVMs which some deployment environments might be stuck with.
28
29 Innovations in SWI Prolog 7 prompted a JPL overhaul (from 3.0.3 to 7.0.1) which changed the public API and warranted a rebrand (as "JPL7", in a nod to SWIPL7).
30
31 (Summary taken from discussion in [this issue](https://github.com/SWI-Prolog/packages-jpl/issues/46).)
2432
2533
2634 ## About this page
177177 Term Y = solutions[0].get("Y");
178178 if (X != Y) {
179179 System.out.println(t7 + " failed:");
180 System.out.println(Util.toString(solutions[0]));
180 System.out.println(Util.subsToString(solutions[0]));
181181 System.out.println("\tThe variables to which X and Y are bound in the first solution should be identical.");
182182 // System.exit(1);
183183 }
185185 Y = solutions[1].get("Y");
186186 if (X == Y) {
187187 System.out.println(t7 + " failed:");
188 System.out.println(Util.toString(solutions[1]));
188 System.out.println(Util.subsToString(solutions[1]));
189189 System.out.println("\tThe variables to which X and Y are bound in the second solution should be distinct.");
190190 // System.exit(1);
191191 }
192192 if (X.equals(Y)) {
193193 System.out.println(t7 + " failed:");
194 System.out.println(Util.toString(solutions[1]));
194 System.out.println(Util.subsToString(solutions[1]));
195195 System.out.println("\tThe variables to which X and Y are bound in the second solution should not be \"equal\".");
196196 // System.exit(1);
197197 }
214214 }
215215
216216 // corresponds with Prolog List: [a-a,a-b]
217 static Term test_9_solution = Util.termArrayToList(new Term[] { new Compound("-", new Term[] { a, a }), new Compound("-", new Term[] { a, b }) });
217 static Term test_9_solution = Term.termArrayToList(new Term[] { new Compound("-", new Term[] { a, a }), new Compound("-", new Term[] { a, b }) });
218218
219219 static void test_9() {
220220 System.out.print("test 9...");
12171217 %
12181218 % ==
12191219 % ?- jpl_pl_lib_version(V).
1220 % V = '7.4.0-alpha'.
1220 % V = '7.6.0-alpha'.
12211221 % ==
12221222
12231223 jpl_pl_lib_version(VersionString) :-
12391239 % Status = alpha.
12401240 % ==
12411241
1242 jpl_pl_lib_version(7, 4, 0, alpha). % jref as blob
1242 jpl_pl_lib_version(7, 6, 0, alpha). % jref as blob
12431243
12441244 %! jpl_c_lib_version(-Version)
12451245 %
5454 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
5555
5656 /* update this to distinguish releases of this C library: */
57 #define JPL_C_LIB_VERSION "7.4.0-alpha"
57 #define JPL_C_LIB_VERSION "7.6.0-alpha"
5858 #define JPL_C_LIB_VERSION_MAJOR 7
59 #define JPL_C_LIB_VERSION_MINOR 4
59 #define JPL_C_LIB_VERSION_MINOR 6
6060 #define JPL_C_LIB_VERSION_PATCH 0
6161 #define JPL_C_LIB_VERSION_STATUS "alpha"
6262
8888 set(CMAKE_JAVA_COMPILE_FLAGS)
8989 endif()
9090
91
9192 add_jar(jpl_jar
9293 SOURCES ${CLS} ${FLI}
93 OUTPUT_NAME jpl)
94 OUTPUT_NAME jpl
95 MANIFEST META-INF/MANIFEST.MF
96 VERSION ${JPL_VERSION}) # VERSION creates jar with the -<version>jar format and a symblic to it.
9497
9598 if(JUNIT_JAR)
9699 add_jar(jpltest
0 Name: org.jpl7
1 Implementation-Title: JPL
2 Implementation-Version: 7.6.0
3 Implementation-Vendor: SWI-Prolog
176176 * @return string representation of an Atom
177177 */
178178 public String toString() {
179 return (JPL.isSimpleName(name) ? name : "'" + name + "'");
179 return (JPL.isSimpleName(name) || isListNil() ? name : "'" + name + "'");
180180 }
181181
182182 /**
226226
227227 /**
228228 * whether this Term denotes (syntax-specifically) a list cell
229 * see this does not check the shape of the second argument to check if it is a list
230 *
231 * So a list pair may not be a list itself and hence isList() will return false
232 * as the second argument many not be a list
229233 *
230234 * @return whether this Term denotes (syntax-specifically) a list cell
231235 */
280284 }
281285
282286
283
284 /**
285 * a prefix functional representation of a Compound of the form name(arg1,...), where 'name' is quoted iff necessary
286 * (to be valid Prolog soutce text) and each argument is represented according to its toString() method.
287 /**
288 *
289 * a prefix functional representation of a Compound of the form name(arg1,...),
290 * where 'name' is quoted iff necessary
291 * (to be valid Prolog source text) and each argument is represented according to its
292 * toString() method.
293 *
294 * Lists are represented depending on JPL.LIST_TOSTRING_TEXTUAL
287295 *
288296 * @return string representation of an Compound
289297 */
290298 public String toString() {
291 return JPL.quotedName(name) + (args.length > 0 ? "(" + Term.toString(args) + ")" : "");
292 }
299 if (isListPair() && JPL.LIST_TOSTRING_TEXTUAL) { // output nice Prolog [.,.,.,.,] format, not prefix format
300 String head_str = arg(1).toString(); // must be at least 1 arg in compound
301 String tail_str;
302 if (arg(2).isListNil()) {
303 return String.format("[%s]", head_str);
304 } else {
305 tail_str = arg(2).toString();
306 StringBuilder builder = new StringBuilder(tail_str);
307 if (arg(2).isListPair()) {
308 builder.deleteCharAt(builder.length()-1); // remove closing ]
309 builder.deleteCharAt(0); // remove opening [
310 }
311 return String.format("[%s, %s]", head_str, builder.toString());
312 }
313 } // just return lists in pre-fix as '[|]'(head, '[|]'(head, '[|]'(head, .....)
314 return JPL.quotedName(name) +
315 (args.length > 0 ? "(" + Term.toString(args) + ")" : "");
316 }
317
318
293319
294320 /**
295321 * the type of this term, as jpl.fli.Prolog.COMPOUND
7575 public static String LIST_PAIR = LIST_PAIR_MODERN; // default unless/until
7676 // setTraditional() is
7777 // called successfully
78 // whether we want lists to be printed in pre-fix '[|]'(head, tails) or textual [....] format
79 public static boolean LIST_TOSTRING_TEXTUAL = true;
7880
7981 private static String nativeLibraryName = "jpl";
8082 private static String nativeLibraryDir = null;
165165 * @throws JPLException if term provided is not of right sort Atom or Compound
166166 */
167167 public Query(String text) {
168 this(Util.textToTerm(text));
168 this(Term.textToTerm(text));
169169 }
170170
171171
204204 * the arguments of this Query's goal
205205 */
206206 private static Term buildQueryTerm(String text, Term[] args) {
207 Term t = Util.textToTerm(text);
207 Term t = Term.textToTerm(text);
208208 if (t instanceof Atom) {
209209 return new Compound(text, args);
210210 } else {
435435 Term exception_term = Term.getTerm(new HashMap<term_t, Variable>(), exception_term_t);
436436 close();
437437 throw new PrologException(exception_term);
438 } else {
438 } else { // no more solution, close the query
439439 close();
440440 return false;
441441 }
455455
456456 /**
457457 * Used to be used only by Utils.textToTerm but code has been integrated there already
458 * @return
458 * @return a substituion from variable names to terms
459459 */
460460 @Deprecated
461461 public final Map<String, Term> getSubstWithNameVars() {
562562 String BindingVarName = ((Variable) BindingVarTerm).name; // its textual name ("Bindings" in example)
563563
564564 Term TermVar = args[args.length - 2]; // the Query's last arg: a variable binding list; type Variable
565 String TermVarName = ((Variable) TermVar).name; // its textual name ("Bindings" in example)
565 // String TermVarName = ((Variable) TermVar).name; // its textual name ("Bindings" in example)
566566
567567 // SECOND, we store what B was bound to as JPL Compound list instance BindingVarValue
568568 // If B was bound to ['X' = _1, 'Y' = _2] in the current solution
5959 * returns the i-th (1+) argument of a Term;
6060 *
6161 * defined only for Compound
62 *
62 *
6363 * @param i the index of argument to return
6464 * @return the i-th argument of a (Compound) Term
6565 * @throws JPLException if Term is not a Compound
104104 throw new JPLException("atomType() is undefined for " + this.typeName());
105105 }
106106
107
108 /**
109 * Converts a Prolog source text to a corresponding JPL Term (in which each Variable has the appropriate name from
110 * the source text).
107 /**
108 * The name of an Atom, Compound or Variable.
109 *
110 * @return the name of an Atom, Compound or Variable.
111 * @throws JPLException
112 * if this Term is not an Atom, Compound or Variable.
113 */
114 public String name() { // overridden in Atom, Compound, Variable
115 throw new JPLException("name() is undefined for " + this.typeName());
116 }
117
118 public void setName(String name) {
119 throw new JPLException("name() is undefined for " + this.typeName());
120 }
121
122 /**
123 * Converts a Prolog source text to a corresponding JPL Term
124 * (in which each Variable has the appropriate name from the source text).
111125 *
112126 * @param text A Prolog source text denoting a term
113127 * @return Term a JPL Term equivalent to the given source text
130144 // it might be better to use PL_chars_to_term()
131145 Query q = new Query(new Compound("atom_to_term",
132146 new Term[] { new Atom(text), new Variable("T"), new Variable("NVdict") }));
147
133148 q.open();
134
135 // quer is open, check if there is a solution
136149 if (q.hasMoreSolutions()) {
137 // cannot use this bc it gives anonymous vars, we lose the names
138 // If we use this we will get T mmapped to Term mother(maria, _1, _2) but we want mother(maria, X, Y)
139150 Map<String, Term> s = q.nextSolution();
140151
141152 // New way of doing it (April 2020)
147158 // Since the Term bound to T will use exactl the Variables _1, _2, etc, by changing their names
148159 // the term T will now use Variables X, Y, etc as wanted!
149160 //Term T = s.get("T");
150 Term[] VarsMapList = Util.listToTermArray(s.get("NVdict")); // this is a Compound list of mappings
161 Term[] VarsMapList = Term.listToTermArray(s.get("NVdict")); // this is a Compound list of mappings
151162 for (Term map : VarsMapList) { // map represents 'X' = _1
152 String VarName = map.arg(1).name(); // extract the symbolic name
153 Variable Var = (Variable) map.arg(2); // extract Variable object
154 Var.setName(VarName);
163 String VarName = map.arg(1).name(); // extract the symbolic name of the variable
164 Variable Var = (Variable) map.arg(2); // extract the Variable object
165 Var.setName(VarName); // set the name of the Variable object to the symbolic name
155166 }
156167
157168 // Old way of doing it (before April 2020) - extremely involved!
158169 //Map<String, Term> s = q.getSolutionWithVarNames();
159170
171
172 // We MUST close the query explicitly or otherwise it will remain at the top of stack because we
173 // just did q.nextSolution() and there may be more
160174 q.close();
175
161176 return (Term) s.get("T");
162177 } else {
178 q.close(); // redundant as q.hasMoreSolutions() would have closed it, but ....
163179 return null;
164180 }
165181 }
166182
183 /**
184 * Converts a Prolog source text to a corresponding JPL Term (in which each Variable has the appropriate name from
185 * the source text), replacing successive occurrences of ? in the text by the corresponding element of Term[]
186 * params. (New in JPL 3.0.4)
187 *
188 * Throws PrologException containing error(syntax_error(_),_) if text is invalid.
189 *
190 * @param text A Prolog source text denoting a term
191 * @param params parameters to be injected in each ?
192 * @return Term a JPL Term equivalent to the given source text
193 */
194 public static Term textParamsToTerm(String text, Term[] params) {
195 return Term.textToTerm(text).putParams(params);
196 }
197
198
199 /**
200 * returns the value (as an int) of an Integer or Float
201 *
202 * @return the value (as an int) of an Integer or Float
203 * @throws JPLException
204 * if this Term is a Compound, Atom or Variable
205 */
206 public int intValue() {
207 throw new JPLException("intValue() is undefined for " + this.typeName());
208 }
209
210 /**
211 * The (long) value of a Float or Integer.
212 *
213 * @return the (long) value of a Float or Integer.
214 * @throws JPLException
215 * if this Term is not a Float or Integer.
216 */
217 public long longValue() { // overridden in Integer, GFloat
218 throw new JPLException("longValue() is undefined for " + this.typeName());
219 }
167220
168221 /**
169222 * the value (as a java.math.BigInteger) of an Integer, whether or not it is big
198251 throw new JPLException("floatValue() is undefined for " + this.typeName());
199252 }
200253
201 /**
202 * This method computes a substitution from a Term (the current object).
203 * The bindings Map varnames_to_Terms maps names of Variables to Terms.
204 * Thus, a substitution is as it is in mathematical logic, a sequence of the form \sigma = {t_0/x_0, ..., t_n/x_n}.
205 * Once the substitution is computed, the substitution should satisfy
206 *
207 * \sigma T = t
208 *
209 * where T is the Term from which the substitution is computed, and t is the term_t which results from the Prolog
210 * query.
211 * <p>
212 *
213 * A second Map, vars_to_Vars, is required: this table holds the Variables that occur (thus far) in the unified term.
214 * The Variable instances in this table are guaranteed to be unique and are keyed on Strings which are Prolog internal
215 * representations of the variables.
216 *
217 * @param varnames_to_Terms
218 * table holding Term substitutions, keyed on names of Variables.
219 * @param vars_to_Vars
220 * A Map holding the Variables that occur thus far in the term; keyed by internal (Prolog) string rep.
221 */
222 protected void getSubst(Map<String, Term> varnames_to_Terms, Map<term_t, Variable> vars_to_Vars) {
223 // overridden in Compound, Variable
224 }
225
226 /**
227 * Just calls computeSubstitution for each Term in the array.
228 *
229 * @param varnames_to_Terms
230 * a Map from variable names to Terms (what each variable string is to be replaced by)
231 * @param vars_to_Vars
232 * a Map from Prolog variables (which may be bounded in the engine) to JPL Variables (which are Java objects)
233 * @param args
234 * an array of Terms to which the substitution is to be applied
235 */
236 protected static void getSubsts(Map<String, Term> varnames_to_Terms, Map<term_t, Variable> vars_to_Vars,
237 Term[] args) {
238 for (int i = 0; i < args.length; ++i) {
239 args[i].getSubst(varnames_to_Terms, vars_to_Vars);
240 }
241 }
242254
243255 /**
244256 * create and return a org.jpl7.Term representation of the given Prolog term
255267 Int64Holder hInt64;
256268 ObjectHolder hObject;
257269 switch (Prolog.term_type(term)) {
258 case Prolog.VARIABLE: // 1
259 for (Iterator<term_t> i = vars_to_Vars.keySet().iterator(); i.hasNext();) {
260 term_t varX = (term_t) i.next(); // a previously seen Prolog
261 // variable
262 if (Prolog.compare(varX, term) == 0) { // identical Prolog
263 // variables?
264 return (Term) vars_to_Vars.get(varX); // return the
265 // associated JPL
266 // Variable
270 case Prolog.VARIABLE: // 1
271 for (Iterator<term_t> i = vars_to_Vars.keySet().iterator(); i.hasNext();) {
272 term_t varX = (term_t) i.next(); // a previously seen Prolog
273 // variable
274 if (Prolog.compare(varX, term) == 0) { // identical Prolog
275 // variables?
276 return (Term) vars_to_Vars.get(varX); // return the
277 // associated JPL
278 // Variable
279 }
267280 }
268 }
269 // otherwise, the Prolog variable in term has not been seen before
270 Variable Var = new Variable(); // allocate a new (sequentially
271 // named) Variable to represent it
272 Var.term_ = term; // this should become redundant...
273 vars_to_Vars.put(term, Var); // use Hashtable(var,null), but only
274 // need set(var)
275 return Var;
276 case Prolog.ATOM: // 2
277 hString = new StringHolder();
278 Prolog.get_atom_chars(term, hString); // ignore return val; assume
279 // success...
280 return new Atom(hString.value, "text");
281 case Prolog.STRING: // 5
282 hString = new StringHolder();
283 Prolog.get_string_chars(term, hString); // ignore return val; assume
284 // success...
285 return new Atom(hString.value, "string");
286 case Prolog.INTEGER: // 3
287 hInt64 = new Int64Holder();
288 if (Prolog.get_integer(term, hInt64)) { // assume it fails if Prolog
289 // integer is bigger than a
290 // Java long...
291 return new org.jpl7.Integer(hInt64.value);
292 } else {
281 // otherwise, the Prolog variable in term has not been seen before
282 Variable Var = new Variable(); // allocate a new (sequentially
283 // named) Variable to represent it
284 Var.term_ = term; // this should become redundant...
285 vars_to_Vars.put(term, Var); // use Hashtable(var,null), but only
286 // need set(var)
287 return Var;
288 case Prolog.ATOM: // 2
293289 hString = new StringHolder();
294 if (Prolog.get_integer_big(term, hString)) {
290 Prolog.get_atom_chars(term, hString); // ignore return val; assume
291 // success...
292 return new Atom(hString.value, "text");
293 case Prolog.STRING: // 5
294 hString = new StringHolder();
295 Prolog.get_string_chars(term, hString); // ignore return val; assume
296 // success...
297 return new Atom(hString.value, "string");
298 case Prolog.INTEGER: // 3
299 hInt64 = new Int64Holder();
300 if (Prolog.get_integer(term, hInt64)) { // assume it fails if Prolog
301 // integer is bigger than a
302 // Java long...
303 return new org.jpl7.Integer(hInt64.value);
304 } else {
305 hString = new StringHolder();
306 if (Prolog.get_integer_big(term, hString)) {
307 // System.out.println("bigint = " + hString.value);
308 return new org.jpl7.Integer(new java.math.BigInteger(hString.value));
309 } else {
310 return new org.jpl7.Integer(-3); // arbitrary
311 }
312 }
313 case Prolog.RATIONAL: // 4
314 hString = new StringHolder();
315 if (Prolog.get_rational(term, hString)) {
295316 // System.out.println("bigint = " + hString.value);
296 return new org.jpl7.Integer(new java.math.BigInteger(hString.value));
317 return new org.jpl7.Rational(hString.value);
297318 } else {
298319 return new org.jpl7.Integer(-3); // arbitrary
299320 }
300 }
301 case Prolog.RATIONAL: // 4
302 hString = new StringHolder();
303 if (Prolog.get_rational(term, hString)) {
304 // System.out.println("bigint = " + hString.value);
305 return new org.jpl7.Rational(hString.value);
306 } else {
307 return new org.jpl7.Integer(-3); // arbitrary
308 }
309 case Prolog.FLOAT: // 5
310 DoubleHolder hFloatValue = new DoubleHolder();
311 Prolog.get_float(term, hFloatValue); // assume it succeeds...
312 return new org.jpl7.Float(hFloatValue.value);
313 case Prolog.COMPOUND: // 6
314 case Prolog.LIST_PAIR: // 9
315 hString = new StringHolder();
316 hInt = new IntHolder();
317 Prolog.get_name_arity(term, hString, hInt); // assume it succeeds
318 Term args[] = new Term[hInt.value];
319 // term_t term1 = Prolog.new_term_refs(hArity.value);
320 for (int i = 1; i <= hInt.value; i++) {
321 term_t termi = Prolog.new_term_ref();
322 Prolog.get_arg(i, term, termi);
323 args[i - 1] = Term.getTerm(vars_to_Vars, termi);
324 }
325 return new Compound(hString.value, args);
326 case Prolog.LIST_NIL: // 7
327 return JPL.LIST_NIL;
328 case Prolog.BLOB: // 8
329 hObject = new ObjectHolder();
330 if (Prolog.get_jref_object(term, hObject)) {
331 if (hObject.value == null) {
332 return JPL.JNULL;
321 case Prolog.FLOAT: // 5
322 DoubleHolder hFloatValue = new DoubleHolder();
323 Prolog.get_float(term, hFloatValue); // assume it succeeds...
324 return new org.jpl7.Float(hFloatValue.value);
325 case Prolog.COMPOUND: // 6
326 case Prolog.LIST_PAIR: // 9
327 hString = new StringHolder();
328 hInt = new IntHolder();
329 Prolog.get_name_arity(term, hString, hInt); // assume it succeeds
330 Term args[] = new Term[hInt.value];
331 // term_t term1 = Prolog.new_term_refs(hArity.value);
332 for (int i = 1; i <= hInt.value; i++) {
333 term_t termi = Prolog.new_term_ref();
334 Prolog.get_arg(i, term, termi);
335 args[i - 1] = Term.getTerm(vars_to_Vars, termi);
336 }
337 return new Compound(hString.value, args);
338 case Prolog.LIST_NIL: // 7
339 return JPL.LIST_NIL;
340 case Prolog.BLOB: // 8
341 hObject = new ObjectHolder();
342 if (Prolog.get_jref_object(term, hObject)) {
343 if (hObject.value == null) {
344 return JPL.JNULL;
345 } else {
346 return new JRef(hObject.value);
347 }
333348 } else {
334 return new JRef(hObject.value);
349 throw new JPLException("unsupported blob type passed from Prolog");
335350 }
336 } else {
337 throw new JPLException("unsupported blob type passed from Prolog");
338 }
339 default: // should never happen
340 throw new JPLException("unknown term type=" + Prolog.term_type(term));
351 default: // should never happen
352 throw new JPLException("unknown term type=" + Prolog.term_type(term));
341353 }
342354 }
343355
357369 * if this Term is a Variable
358370 */
359371 public boolean hasFunctor(String name, int arity) { // overridden in
360 // Atom, Compound
372 // Atom, Compound
361373 return false;
362374 }
363375
412424 return false;
413425 }
414426
415 /**
416 * returns the value (as an int) of an Integer or Float
417 *
418 * @return the value (as an int) of an Integer or Float
419 * @throws JPLException
420 * if this Term is a Compound, Atom or Variable
421 */
422 public int intValue() {
423 throw new JPLException("intValue() is undefined for " + this.typeName());
424 }
427
425428
426429 /**
427430 * whether this Term is an Atom (of any type)
542545 return false;
543546 }
544547
545 /**
546 * Tests whether this Term denotes an empty list within the current syntax ("traditional" or "modern").
547 *
548 * @return whether this Term denotes an empty list within the current syntax ("traditional" or "modern").
549 * @see org.jpl7.JPL#getSyntax()
550 */
551 public boolean isListNil() { // overridden in Atom
552 return false;
553 }
554
555 /**
556 * Tests whether this Term is a list pair within the current syntax ("traditional" or "modern").
557 *
558 * @return whether this Term is a list pair within the current syntax ("traditional" or "modern").
559 */
560 public boolean isListPair() { // overridden in Compound
561 return false;
562 }
563
564
565 /**
566 * Tests whether this Term is a list (empty or list pair)
567 *
568 * @return whether this Term is a list, empty or list pair
569 */
570 public boolean isList() { // overridden in Compound
571 return (isListNil() || isListPair());
572 }
548
573549
574550 /**
575551 * Tests whether this Term is a Variable.
580556 return this instanceof Variable;
581557 }
582558
583 /**
584 * @return the Object which this JRef references
585 * @deprecated Use {@link JRef#object()}
586 */
587 @Deprecated
588 public Object jrefToObject() { // overridden in Compound and JRef
589 throw new JPLException("term is neither a JRef nor a Compound representing @(null)");
590 }
591
592 /**
593 * The length of this list, iff it is one, else an exception is thrown.
594 *
595 * @throws JPLException if the term is not a list
596 * @return the length (as an int) of this list, iff it is one.
597 * @deprecated Use {@link Util#listToLength(Term)}
598 */
599 @Deprecated
600 public final int listLength() {
601 if (this.isListPair()) { // was .hasFunctor(".", 2)
602 return 1 + this.arg(2).listLength(); // TODO eliminate recursion
603 } else if (this.isListNil()) { // was .hasFunctor("[]", 0)
604 return 0;
605 } else {
606 throw new JPLException("term is not a list");
607 }
608 }
609
610 /**
611 * The (long) value of a Float or Integer.
612 *
613 * @return the (long) value of a Float or Integer.
614 * @throws JPLException
615 * if this Term is not a Float or Integer.
616 */
617 public long longValue() { // overridden in Integer, GFloat
618 throw new JPLException("longValue() is undefined for " + this.typeName());
619 }
620
621 /**
622 * The name of an Atom, Compound or Variable.
623 *
624 * @return the name of an Atom, Compound or Variable.
625 * @throws JPLException
626 * if this Term is not an Atom, Compound or Variable.
627 */
628 public String name() { // overridden in Atom, Compound, Variable
629 throw new JPLException("name() is undefined for " + this.typeName());
630 }
631
632 public void setName(String name) {
633 throw new JPLException("name() is undefined for " + this.typeName());
634 }
559
560
635561 /**
636562 * The Object which this org.jpl7.JRef refers to, iff this Term is a JRef or just JPL.JNULL.
637563 *
640566 */
641567 public Object object() { // overridden in JRef
642568 if (this == JPL.JNULL)
643 return null;
644 else
645 throw new JPLException("this term is not a JRef");
646 }
647
648 /**
649 * Returns the JREF term for an object
650 *
651 * @param object object of interest
569 return null;
570 else
571 throw new JPLException("this term is not a JRef");
572 }
573
574 /**
575 * Returns the JREF term for an object
576 *
577 * @param object object of interest
652578 * @return a new JRef which references object, or @(null) if object == null.
653579 * @throws JPLException
654580 * if object is a String.
655581 * @deprecated Use {@link JPL#newJRef}
656582 */
657 @Deprecated
583 @Deprecated
658584 public static final Term objectToJRef(Object object) {
659585 if (object == null) {
660586 return JPL.JNULL;
732658
733659 protected Term putParams1(IntHolder next, Term[] ps) {
734660 switch (this.type()) {
735 case Prolog.COMPOUND:
736 return new Compound(this.name(), putParams2(this.args(), next, ps));
737 case Prolog.ATOM:
738 if (!this.name().equals("?")) {
661 case Prolog.COMPOUND:
662 return new Compound(this.name(), putParams2(this.args(), next, ps));
663 case Prolog.ATOM:
664 if (!this.name().equals("?")) {
665 return this;
666 } else if (next.value >= ps.length) {
667 throw new JPLException("fewer actual params than formal params");
668 } else {
669 return ps[next.value++];
670 }
671 default:
739672 return this;
740 } else if (next.value >= ps.length) {
741 throw new JPLException("fewer actual params than formal params");
742 } else {
743 return ps[next.value++];
744 }
745 default:
746 return this;
747673 }
748674 }
749675
799725 * if this Term is not a JRef
800726 * @deprecated Use {@link JRef#object()}
801727 */
802 @Deprecated
728 @Deprecated
803729 public Object ref() { // overridden in JRef
804730 throw new JPLException("this Term is not a JRef");
805731 }
806732
807 /**
808 * returns an array of Terms whose elements are the respective members of this list, iff it is a list.
809 *
810 * @throws JPLException
811 * if this Term is not a proper list.
812 * @return an array of Terms whose elements are the respective members of this list, iff it is a list.
813 */
814 public final Term[] toTermArray() {
815 try {
816 int len = Util.listToLength(this); // exception if not a well formed list
817 Term[] ts = new Term[len];
818 Term t = this;
819 for (int i = 0; i < len; i++) { // no need to check functor (it's a list)
820 ts[i] = t.arg(1);
821 t = t.arg(2);
822 }
823 return ts;
824 } catch (JPLException e) {
825 throw new JPLException("term is not a proper list");
826 }
733
734 /**
735 * @return the Object which this JRef references
736 * @deprecated Use {@link JRef#object()}
737 */
738 @Deprecated
739 public Object jrefToObject() { // overridden in Compound and JRef
740 throw new JPLException("term is neither a JRef nor a Compound representing @(null)");
827741 }
828742
829743 // ==================================================================/
840754 // Variable with which the term was unified.
841755 // ==================================================================/
842756
757
758 /**
759 * This method computes a substitution from a Term (the current object).
760 * The bindings Map varnames_to_Terms maps names of Variables to Terms.
761 * Thus, a substitution is as it is in mathematical logic, a sequence of the form \sigma = {t_0/x_0, ..., t_n/x_n}.
762 * Once the substitution is computed, the substitution should satisfy
763 *
764 * \sigma T = t
765 *
766 * where T is the Term from which the substitution is computed, and t is the term_t which results from the Prolog
767 * query.
768 * <p>
769 *
770 * A second Map, vars_to_Vars, is required: this table holds the Variables that occur (thus far) in the unified term.
771 * The Variable instances in this table are guaranteed to be unique and are keyed on Strings which are Prolog internal
772 * representations of the variables.
773 *
774 * @param varnames_to_Terms
775 * table holding Term substitutions, keyed on names of Variables.
776 * @param vars_to_Vars
777 * A Map holding the Variables that occur thus far in the term; keyed by internal (Prolog) string rep.
778 */
779 protected void getSubst(Map<String, Term> varnames_to_Terms, Map<term_t, Variable> vars_to_Vars) {
780 // overridden in Compound, Variable
781 }
782
783 /**
784 * Just calls computeSubstitution for each Term in the array.
785 *
786 * @param varnames_to_Terms
787 * a Map from variable names to Terms (what each variable string is to be replaced by)
788 * @param vars_to_Vars
789 * a Map from Prolog variables (which may be bounded in the engine) to JPL Variables (which are Java objects)
790 * @param args
791 * an array of Terms to which the substitution is to be applied
792 */
793 protected static void getSubsts(Map<String, Term> varnames_to_Terms, Map<term_t, Variable> vars_to_Vars,
794 Term[] args) {
795 for (int i = 0; i < args.length; ++i) {
796 args[i].getSubst(varnames_to_Terms, vars_to_Vars);
797 }
798 }
799
843800 /**
844801 * This method is used (by Compound.equals) to determine whether two Term arrays are pairwise equal, where two
845802 * Terms are equal if they satisfy the equals predicate (defined differently in each Term subclass).
895852 */
896853 public abstract String typeName();
897854
898 }
855
856
857
858
859 // ==================================================================/
860 // LIST METHODS
861 //
862 // All tools to deal specifically with lists that could be either
863 // empty list JPL.LIST_NIL or Compound terms with functor [|].
864 // ==================================================================/
865
866 /**
867 * Tests whether this Term denotes an empty list within the current syntax ("traditional" or "modern").
868 *
869 * @return whether this Term denotes an empty list within the current syntax ("traditional" or "modern").
870 * @see org.jpl7.JPL#getSyntax()
871 */
872 public boolean isListNil() { // overridden in Atom
873 return false;
874 }
875
876 /**
877 * Tests whether this Term is a list pair within the current
878 * syntax ("traditional" or "modern").
879 *
880 * Note that a list pair may not be a list itself and hence isList() will return false
881 * as the second argument many not be a list
882 *
883 * @return whether this Term is a list pair within the current syntax ("traditional" or "modern").
884 */
885 public boolean isListPair() { // overridden in Compound
886 return false;
887 }
888
889 /**
890 * whether the Term represents a proper list
891 *
892 * @return whether the Term represents a proper list
893 */
894 public final boolean isList() {
895 return isList(this);
896 }
897
898 /**
899 * whether the Term represents a proper list
900 *
901 * @param term the term to check if it is a list
902 * @return whether the Term represents a proper list
903 */
904 public static final boolean isList(Term term) {
905 return listLength(term) >= 0;
906 }
907
908
909
910 /**
911 * @param term any Term
912 * @return the length of the proper list which the Term represents, else -1
913 */
914 public static int listLength(Term term) {
915 int length = 0;
916 Term head = term;
917 while (head.isListPair()) {
918 length++;
919 head = head.arg(2);
920 }
921 return (head.isListNil() ? length : -1);
922 }
923
924 /**
925 * @return the length of the proper list which the Term represents, else -1
926 */
927 public int listLength() {
928 return Term.listLength(this);
929 }
930
931 /**
932 * Converts an array of String to a corresponding JPL list of atoms
933 *
934 * @param a An array of String objects
935 * @return Term a JPL list of atoms corresponding to the given String array
936 */
937 public static Term stringArrayToList(String[] a) {
938 Term list = JPL.LIST_NIL;
939 for (int i = a.length - 1; i >= 0; i--) {
940 list = new Compound(JPL.LIST_PAIR, new Term[] { new Atom(a[i]), list });
941 }
942 return list;
943 }
944
945 /**
946 * Converts an array of int to a corresponding JPL list
947 *
948 * @param a
949 * An array of int values
950 * @return Term a JPL list corresponding to the given int array
951 */
952 public static Term intArrayToList(int[] a) {
953 Term list = JPL.LIST_NIL; // was new Atom("[]");
954 for (int i = a.length - 1; i >= 0; i--) {
955 list = new Compound(JPL.LIST_PAIR, new Term[] { new org.jpl7.Integer(a[i]), list });
956 }
957 return list;
958 }
959
960 /**
961 * Converts an array of arrays of int to a corresponding JPL list of lists
962 *
963 * @param a
964 * An array of arrays of int values
965 * @return Term a JPL list of lists corresponding to the given int array of arrays
966 */
967 public static Term intArrayArrayToList(int[][] a) {
968 Term list = JPL.LIST_NIL; // was new Atom("[]");
969 for (int i = a.length - 1; i >= 0; i--) {
970 list = new Compound(JPL.LIST_PAIR, new Term[] { intArrayToList(a[i]), list });
971 }
972 return list;
973 }
974
975
976 /**
977 * Converts an array of Terms to a JPL representation of a Prolog list of terms whose members correspond to the
978 * respective array elements.
979 *
980 * @param terms
981 * An array of Term
982 * @return Term a list of the array elements
983 */
984 public static Term termArrayToList(Term[] terms) {
985 Term list = JPL.LIST_NIL; // was new Atom("[]")
986 for (int i = terms.length - 1; i >= 0; --i) {
987 list = new Compound(JPL.LIST_PAIR, new Term[] { terms[i], list });
988 }
989 return list;
990 }
991
992
993 /**
994 * Converts a term representing a list of atoms into an array of Strings, each element
995 * in the array being a String for the corresponding atom
996 * e.g., [a, b, 1
997 *
998 *
999 * @param t a term representing a list of atoms
1000 * @return an array of Strings, each element, null if t is not a list of atoms
1001 */
1002 public static String[] atomListToStringArray(Term t) {
1003 int n = Term.listLength(t);
1004 String[] a;
1005 if (n < 0) {
1006 return null;
1007 } else {
1008 a = new String[n];
1009 }
1010 int i = 0;
1011 Term head = t;
1012 while (head.isListPair()) {
1013 Term x = head.arg(1);
1014 if (x.isAtom()) {
1015 a[i++] = x.name();
1016 } else {
1017 return null;
1018 }
1019 head = head.arg(2);
1020 }
1021 return (head.isListNil() ? a : null);
1022 }
1023
1024
1025
1026 /**
1027 * converts a proper list to an array of terms, else throws an exception
1028 *
1029 * @throws JPLException if the term passed is not itself a Prolog list term
1030 * @return an array of terms whose successive elements are the corresponding members of the list (if it is a list)
1031 */
1032 public static Term[] listToTermArray(Term t) {
1033 int len = Term.listLength(t); // exception if not a well formed list
1034 if (len < 0) {
1035 throw new JPLException("term is not a proper list");
1036 }
1037 Term[] ts = new Term[len];
1038 for (int i = 0; i < len; i++) { // no need to check functor (it's a list)
1039 ts[i] = t.arg(1);
1040 t = t.arg(2);
1041 }
1042 return ts;
1043 }
1044
1045 /**
1046 * converts a proper list to an array of terms, else throws an exception
1047 *
1048 * @throws JPLException if the term passed is not itself a Prolog list term
1049 * @return an array of terms whose successive elements are the corresponding members of the list (if it is a list)
1050 */
1051 public final Term[] listToTermArray() {
1052 return Term.listToTermArray(this);
1053 }
1054
1055 /**
1056 * @deprecated Use org.jpl7.Term.termArrayToList(Term[] terms)
1057 */
1058 @Deprecated
1059 public final Term[] toTermArray() {
1060 return listToTermArray();
1061 }
1062
1063
1064 }
4545 * @param terms
4646 * An array of Term
4747 * @return Term a list of the array elements
48 */
48 * @deprecated Use org.jpl7.Term.termArrayToList(Term[] terms)
49 */
50 @Deprecated
4951 public static Term termArrayToList(Term[] terms) {
50 Term list = JPL.LIST_NIL; // was new Atom("[]")
51 for (int i = terms.length - 1; i >= 0; --i) {
52 list = new Compound(JPL.LIST_PAIR, new Term[] { terms[i], list });
53 }
54 return list;
52 return Term.termArrayToList(terms);
5553 }
5654
5755 /**
6159 * A Map from variable names to Terms.
6260 * @return String A String representation of the variable bindings
6361 */
64 public static String toString(Map<String, Term> varnames_to_Terms) {
62 public static String subsToString(Map<String, Term> varnames_to_Terms) {
6563 if (varnames_to_Terms == null) {
6664 return "[no solution]";
6765 } else {
7371 }
7472 return s;
7573 }
74 }
75
76 /**
77 * @deprecated Use org.jpl7.Util.subsToString(Map<String, Term>)
78 */
79 @Deprecated
80 public static String toString(Map<String, Term> varnames_to_Terms) {
81 return subsToString(varnames_to_Terms);
7682 }
7783
7884 /**
9399 // the cast to Variable is necessary to access the (protected)
94100 // .term_ field
95101 vars_to_Vars.put(((Variable) nvs.arg(1).arg(2)).term_, new Variable(nvs.arg(1).arg(1).name())); // map
96 // the
97 // Prolog
98 // variable
99 // to
100 // a
101 // new,
102 // named
103 // Variable
102 // the
103 // Prolog
104 // variable
105 // to
106 // a
107 // new,
108 // named
109 // Variable
104110 nvs = nvs.arg(2); // advance to next list cell
105111 }
106112 // maybe oughta check that nvs is [] ?
107113 return vars_to_Vars;
108114 } catch (java.lang.ClassCastException e) { // nvs is not of the expected
109 // structure
115 // structure
110116 return null;
111117 }
112118 }
113119
114120 /**
115 * Converts a Prolog source text to a corresponding JPL Term (in which each Variable has the appropriate name from
116 * the source text).
117 *
118 * @param text A Prolog source text denoting a term
119 * @return Term a JPL Term equivalent to the given source text
120 * @throws PrologException containing error(syntax_error(_),_) if text is invalid as a term.
121121 * @deprecated Use org.jpl7.Term.textToTerm(String text)
122122 */
123123 @Deprecated
141141 }
142142
143143 /**
144 * Converts an array of String to a corresponding JPL list
145 *
146 * @param a
147 * An array of String objects
148 * @return Term a JPL list corresponding to the given String array
149 */
144 * @deprecated Use org.jpl7.Term.stringArrayToList(String[] a)
145 */
146 @Deprecated
150147 public static Term stringArrayToList(String[] a) {
151 Term list = JPL.LIST_NIL;
152 for (int i = a.length - 1; i >= 0; i--) {
153 list = new Compound(JPL.LIST_PAIR, new Term[] { new Atom(a[i]), list });
154 }
155 return list;
156 }
157
158 /**
159 * Converts an array of int to a corresponding JPL list
160 *
161 * @param a
162 * An array of int values
163 * @return Term a JPL list corresponding to the given int array
164 */
148 return Term.stringArrayToList(a);
149 }
150
151 /**
152 * @deprecated Use org.jpl7.Term.intArrayToList(int[] a)
153 */
154 @Deprecated
165155 public static Term intArrayToList(int[] a) {
166 Term list = JPL.LIST_NIL; // was new Atom("[]");
167 for (int i = a.length - 1; i >= 0; i--) {
168 list = new Compound(JPL.LIST_PAIR, new Term[] { new org.jpl7.Integer(a[i]), list });
169 }
170 return list;
171 }
172
173 /**
174 * Converts an array of arrays of int to a corresponding JPL list of lists
175 *
176 * @param a
177 * An array of arrays of int values
178 * @return Term a JPL list of lists corresponding to the given int array of arrays
179 */
156 return Term.intArrayToList(a);
157 }
158
159 /**
160 * @deprecated Use org.jpl7.Term.intArrayArrayToList(int[][] a)
161 */
162 @Deprecated
180163 public static Term intArrayArrayToList(int[][] a) {
181 Term list = JPL.LIST_NIL; // was new Atom("[]");
182 for (int i = a.length - 1; i >= 0; i--) {
183 list = new Compound(JPL.LIST_PAIR, new Term[] { intArrayToList(a[i]), list });
184 }
185 return list;
186 }
187
188 /**
189 * whether the Term represents a proper list
190 *
191 * @param term the term to check if it is a list
192 * @return whether the Term represents a proper list
193 */
164 return Term.intArrayArrayToList(a);
165 }
166
167 /**
168 * @deprecated Use {@link Term#isList(Term)}
169 */
170 @Deprecated
194171 public static final boolean isList(Term term) {
195 return listToLength(term) >= 0;
196 }
172 return Term.isList(term);
173 }
174
197175
198176 /**
199177 * @param term any Term
200178 * @return the length of the proper list which the Term represents, else -1
201 */
179 * @deprecated Use {@link Term#listLength(Term)}
180 */
181 @Deprecated
202182 public static int listToLength(Term term) {
203 int length = 0;
204 Term head = term;
205 while (head.isListPair()) {
206 length++;
207 head = head.arg(2);
208 }
209 return (head.isListNil() ? length : -1);
210 }
211
212 /**
213 * converts a proper list to an array of terms, else throws an exception
214 *
215 * @param t a list term
216 * @throws JPLException if the term passed is not itself a Prolog list term
217 * @return an array of terms whose successive elements are the corresponding members of the list (if it is a list)
218 */
183 return Term.listLength(term);
184 }
185
186 /**
187 * @deprecated Use {@link Term#listToTermArray(Term)}
188 */
189 @Deprecated
219190 public static Term[] listToTermArray(Term t) {
220191 try {
221 int len = Util.listToLength(t); // exception if not a list
192 int len = Term.listLength(t); // exception if not a list
222193 Term[] ts = new Term[len];
223194 for (int i = 0; i < len; i++) {
224195 ts[i] = t.arg(1);
230201 }
231202 }
232203
204 /**
205 * @deprecated Use {@link Term#atomListToStringArray(Term)}
206 */
207 @Deprecated
233208 public static String[] atomListToStringArray(Term t) {
234 int n = listToLength(t);
209 int n = Term.listLength(t);
235210 String[] a;
236211 if (n < 0) {
237212 return null;
22
33 class Version {
44 public final int major = 7;
5 public final int minor = 4; // jref as blob
5 public final int minor = 6; // jref as blob
66 public final int patch = 0;
77 public final String status = "alpha";
88 }
2929 public static void setUp() {
3030
3131 setUpClass();
32 Query.hasSolution(String.format("consult('%s/test_quoted_module.pl')", test_dir)); // only because we call e.g. jpl_pl_syntax/1 below
32 Query.hasSolution(String.format("consult('%s/test_quoted_module.pl')", test_dir)); // .pl file to be used
3333 }
3434
3535
6161 name = "existence_error(procedure, '/'(pepe, 1))";
6262 // name = "'/'(pepe, 1)";
6363 name = "'$c_call_prolog'";
64 t = Util.textToTerm(name);
64 t = Term.textToTerm(name);
6565 assertEquals("matching text-term", name, t.toString());
6666 }
6767
165165 public void testUtilListToTermArray1() {
166166 String goal = "T = [a,b,c]";
167167 Term list = Query.oneSolution(goal).get("T");
168 Term[] array = Util.listToTermArray(list);
168 Term[] array = Term.listToTermArray(list);
169169 assertTrue(array[2].isAtom() && array[2].name().equals("c"));
170170 }
171171
173173 public void testTermToTermArray1() {
174174 String goal = "T = [a,b,c]";
175175 Term list = Query.oneSolution(goal).get("T");
176 Term[] array = list.toTermArray();
176 Term[] array = list.listToTermArray();
177177 assertTrue(array[2].isAtom() && array[2].name().equals("c"));
178178 }
179179
182182 @Test
183183 public void testTextToTerm1() {
184184 String text = "fred(B,p(A))";
185 Term t = Util.textToTerm(text);
185 Term t = Term.textToTerm(text);
186186 assertTrue("Util.textToTerm() converts \"fred(B,p(A))\" to a corresponding Term",
187187 t.hasFunctor("fred", 2) && t.arg(1).isVariable() && t.arg(1).name().equals("B")
188188 && t.arg(2).hasFunctor("p", 1) && t.arg(2).arg(1).isVariable()
195195 public void testTextToTerm2() {
196196 String text1 = "fred(?,2,?)";
197197 String text2 = "[first(x,y),A]";
198 Term plist = Util.textToTerm(text2);
199 Term[] ps = plist.toTermArray();
200 Term t = Util.textToTerm(text1).putParams(ps);
198 Term plist = Term.textToTerm(text2);
199 Term[] ps = plist.listToTermArray();
200 Term t = Term.textToTerm(text1).putParams(ps);
201201 assertTrue("fred(?,2,?) .putParams( [first(x,y),A] )",
202202 t.hasFunctor("fred", 3) && t.arg(1).hasFunctor("first", 2) && t.arg(1).arg(1).hasFunctor("x", 0)
203203 && t.arg(1).arg(2).hasFunctor("y", 0) && t.arg(2).hasFunctor(2, 0) && t.arg(3).isVariable()
11
22 import org.jpl7.*;
33 import org.jpl7.Integer;
4 import org.jpl7.fli.Prolog;
5 import org.junit.Before;
64 import org.junit.BeforeClass;
75 import org.junit.Rule;
86 import org.junit.Test;
5048 ///////////////////////////////////////////////////////////////////////////////
5149
5250
51 private static Term[] terms_pair_integers = new Term[]{new Integer(1), new Integer(2)};
52 private static Term[] terms_integers = new Term[]{new Integer(1), new Integer(2), new Integer(3)};
53 private static Term[] terms_atoms = new Term[]{new Atom("a"), new Atom("b"), new Atom("c")};
54
55 // Several list terms of numbers
56 private static Term list_empty = Term.textToTerm("[]");
57 private static Term list_unit = Term.textToTerm("[1]");
58 private static Term list_unit_complex = Term.textToTerm("[[1,2,3]]");
59 private static Term list_simple = Term.textToTerm("[1,2,3]");
60 private static Term list_complex = Term.textToTerm("[1, [1,2,3], 3]");
61
62 private static Term[] lists_many = new Term[]{list_empty, list_unit, list_unit_complex, list_simple, list_complex};
63 private static Term[] lists_many_noempty = new Term[]{list_unit, list_unit_complex, list_simple, list_complex};
64
65
5366
5467 ///////////////////////////////////////////////////////////////////////////////
5568 // TESTS
5669 ///////////////////////////////////////////////////////////////////////////////
5770
58
59 @Test
60 public void testArrayToList1() {
61 Term l2 = Util.termArrayToList(
62 new Term[]{new Atom("a"), new Atom("b"), new Atom("c"), new Atom("d"), new Atom("e")});
63 Query q9 = new Query(new Compound("append", new Term[]{new Variable("Xs"), new Variable("Ys"), l2}));
64 assertTrue("append(Xs,Ys,[a,b,c,d,e]) has 6 solutions", q9.allSolutions().length == 6);
65 }
66
67 @Test
68 public void testArrayToList2() {
69 String goal = "append(Xs,Ys,[a,b,c,d,e])";
70 assertTrue(goal + " has 6 solutions", Query.allSolutions(goal).length == 6);
71 }
72
73 @Test
74 public void testArrayToList3() {
75 final String[] expectedSolutions = { "a", "b", "c", "d", "e"};
76
77 Term l2 = Util.termArrayToList(
78 new Term[] { new Atom("a"), new Atom("b"), new Atom("c"), new Atom("d"), new Atom("e") });
79 Query query = new Query(new Compound("member", new Term[] { new Variable("X"), l2 }));
80
81 Map<String, Term>[] sol = query.allSolutions();
82 for (int i = 0; i < sol.length; i++) {
83 assertEquals(expectedSolutions[i], sol[i].get("X").toString());
84 }
85 }
86
87 @Test
88 public void testArrayToList4() {
89 final String[] expectedSolutionsX = { "[]", "[a]", "[a, b]", "[a, b, c]"};
90 final String[] expectedSolutionsY = { "[a, b, c]", "[b, c]", "[c]", "[]"};
91
92 Term l2 = Util.termArrayToList(
93 new Term[] { new Atom("a"), new Atom("b"), new Atom("c") });
94 Query query = new Query(new Compound("append", new Term[] { new Variable("X"), new Variable("Y"), l2 }));
95
96 Map<String, Term>[] sol = query.allSolutions();
97 for (int i = 0; i < sol.length; i++) {
98
99 String ListX = Arrays.toString(Util.atomListToStringArray(sol[i].get("X")));
100 String ListY = Arrays.toString(Util.atomListToStringArray(sol[i].get("Y")));
101
102
103 assertEquals("Bad X in append(X, Y, [a, b, c])", expectedSolutionsX[i], ListX);
104 assertEquals("Bad Y in append(X, Y, [a, b, c])", expectedSolutionsY[i], ListY);
105
106 }
107 }
108
109
110
111
112
113
114
115 @Test
116 public void testLength1() {
117 Query q5 = new Query(new Compound("length", new Term[]{new Variable("Zs"), new Integer(2)}));
118 Term zs = q5.oneSolution().get("Zs");
119 assertTrue("length(Zs,2) binds Zs to a list of two distinct variables " + zs.toString(),
120 zs.isListPair() && zs.arg(1).isVariable() && zs.arg(2).isListPair() && zs.arg(2).arg(1).isVariable()
121 && zs.arg(2).arg(2).isListNil() && !zs.arg(1).name().equals(zs.arg(2).arg(1).name()));
122 }
12371
12472 @Test
12573 public void testListNil1() {
13381 }
13482 }
13583
84
85 @Test
86 public void testListNil2() {
87 Term x;
88
89 x = Query.oneSolution("X = []").get("X");
90 assertTrue("term should be empty list", x.isListNil());
91 assertTrue("Util.isList on empty list", Term.isList(x));
92 assertTrue("term is not a ListPair", !x.isListPair());
93
94 x = Query.oneSolution("X = [1, 2, 3]").get("X");
95 assertTrue("term should NOT be empty list", !x.isListNil());
96 assertTrue("Util.isList on non-empty list", Term.isList(x));
97 assertTrue("term is not a ListPair", x.isListPair());
98 }
99
100 @Test
101 public void testIsList() {
102 final String[] options = { "[]", "[1]", "[1,2,3]", "[1, [a, b, c], 2]", "[[1,2,3]]"};
103
104 Term x;
105 for (String opt : options) {
106 x = Query.oneSolution(String.format("X = %s", opt)).get("X");
107 assertTrue("term should be empty list - Util", Term.isList(x));
108 assertTrue("term should be empty list - Util", x.isList());
109 }
110 }
111
112
113
114 @Test
115 public void testIsPairList() {
116 final String[] options = { "[]", "[1]", "[1,2,3]", "[1, [a, b, c], 2]", "[[1,2,3]]"};
117
118 Term t;
119 for (Term t2 : lists_many_noempty) {
120 String msg = String.format("term %s should be a pair list", t2.toString());
121 assertTrue(msg, t2.isListPair());
122 }
123
124 t = new Compound(JPL.LIST_PAIR, terms_pair_integers);
125 assertTrue("term is a pair list (even though second arg is not a list)", t.isListPair());
126
127
128 assertTrue("empty list term is not a list pair", !JPL.LIST_NIL.isListPair());
129
130 t = new Compound(JPL.LIST_PAIR, terms_integers);
131 assertTrue("term is not a pair list, has more than two arguments", !t.isListPair());
132
133 t = new Compound("hello", terms_integers);
134 assertTrue("term is not a pair list, not JPL.PAIR_LIST functor", !t.isListPair());
135
136 }
137
138 @Test
139 public void testIsPairList2() {
140 Term t = new Compound(JPL.LIST_PAIR,
141 new Term[]{new Integer(1), new Integer(2)});
142
143 String msg = String.format("term %s should be a pair list", t.toString());
144 assertTrue(msg, t.isListPair());
145
146 assertEquals("[1, 2]", t.toString());
147 }
148
136149 @Test
137150 public void testListCons1() {
138151 Term x = Query.oneSolution("X = [a]").get("X");
141154 } else {
142155 assertTrue("list constructor is [|]/2", x.isCompound() && x.name().equals("[|]"));
143156 }
157 }
158
159
160
161
162
163 @Test
164 public void testArrayToList1() {
165 Term l = Term.termArrayToList(
166 new Term[]{new Atom("a"), new Atom("b"), new Atom("c"),
167 new Atom("d"), new Atom("e")});
168 Query q = new Query(new Compound("append",
169 new Term[]{new Variable("Xs"), new Variable("Ys"), l}));
170
171 assertTrue("append(Xs,Ys,[a,b,c,d,e]) has 6 solutions", q.allSolutions().length == 6);
172 }
173
174
175 @Test
176 public void testArrayToList2() {
177 final String[] expectedSolutions = { "a", "b", "c", "d", "e"};
178
179 Term l = Term.termArrayToList(
180 new Term[] { new Atom("a"), new Atom("b"), new Atom("c"),
181 new Atom("d"), new Atom("e") });
182 Query query = new Query(new Compound("member",
183 new Term[] { new Variable("X"), l }));
184
185 Map<String, Term>[] sol = query.allSolutions();
186 for (int i = 0; i < sol.length; i++) {
187 assertEquals(expectedSolutions[i], sol[i].get("X").toString());
188 }
189 }
190
191 @Test
192 public void testArrayToList3() {
193 final String[] expectedSolutionsX = { "[]", "[a]", "[a, b]", "[a, b, c]"};
194 final String[] expectedSolutionsY = { "[a, b, c]", "[b, c]", "[c]", "[]"};
195
196 Term l = Term.termArrayToList(
197 new Term[] { new Atom("a"), new Atom("b"), new Atom("c") });
198 Query q = new Query(new Compound("append", // append(X, Y, [a, b, c])
199 new Term[] { new Variable("X"), new Variable("Y"), l }));
200
201 Map<String, Term>[] sol = q.allSolutions();
202 for (int i = 0; i < sol.length; i++) {
203
204 String ListX = Arrays.toString(Term.atomListToStringArray(sol[i].get("X")));
205 String ListY = Arrays.toString(Term.atomListToStringArray(sol[i].get("Y")));
206
207
208 assertEquals("Bad X in append(X, Y, [a, b, c])", expectedSolutionsX[i], ListX);
209 assertEquals("Bad Y in append(X, Y, [a, b, c])", expectedSolutionsY[i], ListY);
210
211 }
212 }
213
214
215 @Test
216 public void testStringToList() {
217 String goal = "append(Xs,Ys,[a,b,c,d,e])";
218 assertTrue(goal + " has 6 solutions", Query.allSolutions(goal).length == 6);
219 }
220
221
222
223
224
225 @Test
226 public void testLength1() {
227 Query q5 = new Query(new Compound("length", new Term[]{new Variable("Zs"), new Integer(2)}));
228 Term zs = q5.oneSolution().get("Zs");
229 assertTrue("length(Zs,2) binds Zs to a list of two distinct variables " + zs.toString(),
230 zs.isListPair() && zs.arg(1).isVariable() &&
231 zs.arg(2).isListPair() && zs.arg(2).arg(1).isVariable()
232 && zs.arg(2).arg(2).isListNil() &&
233 !zs.arg(1).name().equals(zs.arg(2).arg(1).name()));
144234 }
145235
146236 @Test
187277 // }
188278
189279
280 @Test
281 public void test_textToTerm_and_toString() {
282 final String[] options = { "[]", "[1,2,3]", "[1]", "[1,g(2,3,5),[1,2,3],abc,[1],a,[],b]", "[[1,2,3]]" };
283 final String[] options2 = { "[]", "[1, 2, 3]", "[1]", "[1, g(2, 3, 5), [1, 2, 3], abc, [1], a, [], b]", "[[1, 2, 3]]" };
284
285 Term t;
286 Term s;
287 String msg;
288 String opt, opt2;
289 for (int i = 0; i < options.length; i++) {
290 opt = options[i];
291 msg = String.format("test Term.textToTerm on: %s", opt);
292
293 t = Term.textToTerm(opt);
294 s = Query.oneSolution(String.format("X = %s", opt)).get("X");
295 assertTrue(msg, t.isList());
296 assertEquals(t, s);
297
298 opt2 = options2[i];
299 msg = String.format("test Term.toString() on: %s", opt);
300 assertEquals(msg, opt2, s.toString());
301
302 }
303 }
304
305
190306 }
5454
5555 @Test
5656 public void testTerm1() {
57 Term args = Util.textToTerm("[1,2,3,4,5]");
57 Term args = Term.textToTerm("[1,2,3,4,5]");
5858 Term t = new Compound("member", new Term[] { new Integer(1), args } );
5959 Query q = new Query(t);
6060 assertTrue("Query should have succeded, but it did not!", q.hasSolution());
9898
9999 @Test
100100 public void testString3() {
101 Term[] args = new Term[] { new Integer(1), Util.textToTerm("[1,2,3,4,5]") };
101 Term[] args = new Term[] { new Integer(1), Term.textToTerm("[1,2,3,4,5]") };
102102
103103 Query q = new Query("member(?, ?)", args);
104104 assertTrue("Query should have succeded, but it did not!", q.hasSolution());
106106
107107 @Test
108108 public void testString4() {
109 Term[] args = new Term[] { new Integer(1), Util.textToTerm("[1,2,3,4,5]") };
109 Term[] args = new Term[] { new Integer(1), Term.textToTerm("[1,2,3,4,5]") };
110110
111111 Query q = new Query("member", args);
112112 assertTrue("Query should have succeded, but it did not!", q.hasSolution());
153153 // Error in number of placeholder matching arguments (too many terms)
154154 @Test
155155 public void testStringErr3() {
156 Term[] args = new Term[] { new Integer(1), Util.textToTerm("[1,2,3,4,5]") };
156 Term[] args = new Term[] { new Integer(1), Term.textToTerm("[1,2,3,4,5]") };
157157
158158 try {
159159 Query q = new Query("member(?, ?, ?)", args);
169169 // Error in number of placeholder matching arguments (too many terms)
170170 @Test
171171 public void testStringErr4() {
172 Term[] args = new Term[] { new Integer(1), Util.textToTerm("[1,2,3,4,5]") };
172 Term[] args = new Term[] { new Integer(1), Term.textToTerm("[1,2,3,4,5]") };
173173
174174 try {
175175 Query q = new Query("member(?)", args);
528528
529529 list_clauses([]).
530530 list_clauses([H|T]) :-
531 portray_clause(H),
531 ( system_undefined(H)
532 -> true
533 ; portray_clause(H)
534 ),
532535 list_clauses(T).
536
537 system_undefined((undefined :- tnot(undefined))).
538 system_undefined((answer_count_restraint :- tnot(answer_count_restraint))).
539 system_undefined((radial_restraint :- tnot(radial_restraint))).
533540
534541 dict_bindings(Dict, Bindings) :-
535542 dict_pairs(Dict, _Tag, Pairs),
6969 * [[rdf_retractall/3]]
7070 * [[rdf_retractall/4]]
7171 * [[rdf_update/4]]
72 * [[rdf_update/5]]
7372
7473 ## Update view, transactions and snapshots {#semweb-update-view}
7574
363363 %! rdf_update(+S, +P, +O, ++Action) is det.
364364 %! rdf_update(+S, +P, +O, +G, ++Action) is det.
365365 %
366 % Replaces one of the three fields on the matching triples
366 % Replaces one of the three (four) fields on the matching triples
367367 % depending on Action:
368368 %
369369 % * subject(Resource)
375375 % literal(Value).
376376 % * graph(Graph)
377377 % Moves the triple from its current named graph to Graph.
378 % This only works with rdf_update/4 and will throw an error when
379 % used with rdf_update/3.
380 %
381 % The argument matching the action must be ground. If this
382 % argument is equivalent to the current value, no action is
383 % performed. Otherwise, the requested action is performed on all
384 % matching triples. For example, all resources typed `rdfs:Class`
385 % can be changed to `owl:Class` using
378 % This only works with rdf_update/5 and throws an error when
379 % used with rdf_update/4.
380 %
381 % The argument matching Action must be ground. If this argument is
382 % equivalent to the current value, no action is performed. Otherwise,
383 % the requested action is performed on all matching triples. For
384 % example, all resources typed `rdfs:Class` can be changed to
385 % `owl:Class` using
386386 %
387387 % ```
388388 % ?- rdf_update(_, rdf:type, rdfs:'Class',
566566 % useful to remove all triples coming from a loaded file. See also
567567 % rdf_unload/1.
568568
569 %! rdf_update(+Subject, +Predicate, +Object, +Action) is det.
570 %
571 % Replaces one of the three fields on the matching triples
569 %! rdf_update(+Subject, +Predicate, +Object, ++Action) is det.
570 %! rdf_update(+Subject, +Predicate, +Object, +Graph, ++Action) is det
571 %
572 % Replaces one of the three (four) fields on the matching triples
572573 % depending on Action:
573574 %
574575 % * subject(Resource)
580581 % literal(Value).
581582 % * graph(Graph)
582583 % Moves the triple from its current named graph to Graph.
583
584 %! rdf_update(+Subject, +Predicate, +Object, +Graph, +Action) is det
585 %
586 % As rdf_update/4 but allows for specifying the graph.
584 % This only works with rdf_update/5 and throws an error when
585 % used with rdf_update/4.
587586
588587
589588 /*******************************
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2000-2015, University of Amsterdam
5 Copyright (c) 2000-2020, University of Amsterdam
66 VU University Amsterdam
7 CWI, Amsterdam
78 All rights reserved.
89
910 Redistribution and use in source and binary forms, with or without
27262727 validate_completeness(dtd_parser *p, sgml_environment *env)
27272728 { if ( !complete(env) )
27282729 { wchar_t buf[MAXNMLEN+50];
2729
2730 swprintf(buf, MAXNMLEN+50, L"Incomplete element: <%s>",
2730 buf[MAXNMLEN+49] = 0;
2731 swprintf(buf, MAXNMLEN+49, L"Incomplete element: <%s>",
27312732 env->element->name->name);
27322733
27332734 gripe(p, ERC_VALIDATE, buf); /* TBD: expected */
54805481 static wchar_t *
54815482 format_location(wchar_t *s, size_t len, dtd_srcloc *l)
54825483 { int first = TRUE;
5483 wchar_t *e = &s[len];
5484
5484 wchar_t *e = &s[len-1];
5485
5486 assert(len > 0);
54855487 if ( !l || l->type == IN_NONE || len == 0 )
54865488 return s;
54875489
5488 e[-1] = L'\0';
5490 *e = L'\0';
54895491 for( ; l && l->type != IN_NONE;
54905492 l = l->parent, first = FALSE )
54915493 { if ( !first )
55865588 int dtdmode = FALSE;
55875589 void *freeme = NULL;
55885590
5591 buf[MAX_MESSAGE_LEN] = 0;
55895592 va_start(args, e);
55905593
55915594 memset(&error, 0, sizeof(error));
5050 /** get configured values, with reasonable defaults
5151 */
5252 Preferences::Preferences(QObject *parent) :
53 QSettings("SWI-Prolog", "pqConsole", parent)
53 QSettings("swi-prolog", "pqConsole", parent)
5454 { qDebug() << "Loading preferences from " << fileName();
5555
56 console_font = value("console_font", QFont("courier", 12)).value<QFont>();
56 QFont default_font("Monospace");
57 default_font.setStyleHint(QFont::Monospace);
58 console_font = value("console_font", default_font).value<QFont>();
5759 wrapMode = static_cast<ConsoleEditBase::LineWrapMode>(value("wrapMode", ConsoleEditBase::WidgetWidth).toInt());
5860
5961 console_out_fore = value("console_out_fore", 0).toInt();
7575 ! to use tabs (@on). PceEmacs detects body_indentation and
7676 ! indent_tabs from the first clause when editing an existing file.
7777
78 !emacs_prolog_mode.body_indentation: 4
79 !emacs_prolog_mode.cond_indentation: 4
80 !emacs_prolog_mode.indent_tabs: @off
78 !emacs_prolog_mode.body_indentation: 4
79 !emacs_prolog_mode.cond_indentation: 4
80 !emacs_prolog_mode.indent_tabs: @off
81
82 ! How to add a new set of dependencies for ->update_dependencies
83 ! (^c^d). Possible values are autoload/1, autoload/2, use_module/1
84 ! and use_module/2.
85
86 !emacs_prolog_mode.dependency_directive: autoload/2
8187
8288 ! Comment column for M-; This may be refined by mode (e.g. emacs_prolog_mode,
8389 ! etc.)
+0
-75
packages/xpce/INFO less more
0 XPCE: a portable GUI toolkit
1 ============================
2
3 Author:
4 =======
5
6 Jan Wielemaker jan@swi.psy.uva.nl
7 Anjo Anjewierden anjo@swi.psy.uva.nl
8 SWI,
9 University of Amsterdam
10 Roetersstraat 15
11 1018 WB Amsterdam
12 The Netherlands
13 http://www.swi.psy.uva.nl
14
15 URL:
16 ====
17
18 xpce-bugs@swi.psy.uva.nl Bug reports
19 xpce-request@swi.psy.uva.nl General info and mailing list
20 xpce@swi.psy.uva.nl Mailing list
21 http://swi-prolog.org/packages/xpce Project Home Page
22 ftp://swi.psy.uva.nl/xpce Various public resources
23
24 OS Platforms:
25 =============
26
27 Unix/X11 (most brands, including 64-bit platforms)
28 Win32 (Windows 95/98/ME, NT/2000/XP, Intel)
29
30 Hosting languages
31 =================
32
33 SWI-Prolog http://www.swi-prolog.org
34
35 Ports to the following have existed and are in not too bad
36 shape.
37
38 Quintus Prolog http://www.sics.se/quintus/
39 SICStus Prolog http://www.sics.se/
40
41 Considering the costs of maintaining portable Prolog
42 code given the current status of the standard, we will only
43 produce versions for other Prolog systems if this situation
44 improves or we get hold of sufficient resources to maintain
45 portability.
46
47 Documentation
48 =============
49
50 # Programming in XPCE/Prolog
51 Userguide to get you started. Explains the interface, object
52 model as well as creating new classes. Provides `technique'
53 sections, explaining how commonly encountered problems may
54 be solved using XPCE.
55
56 # Course Notes
57 Document explaining roughly the same material as ``Programming
58 in XPCE/Prolog'' in a condensed form.
59
60 # Reference Manual
61 Available using the built-in online help-system. Includes
62 various fully dynamic viewpoints to the reference material.
63
64
65 Licenses
66 ========
67
68 * XPCE is distributed as free software with sufficient escapes
69 to generate non-free applications. The license conditions are
70 in the source-files. An overall discussion on the license
71 issues can be found with SWI-Prolog, which is distributed under
72 exactly these conditions. For details, see:
73
74 http://www.swi-prolog.org/license.html
+0
-232
packages/xpce/INSTALL.md less more
0 # Installing XPCE/Prolog from source
1
2 Normally, xpce is provided as `packages/xpce` in the SWI-Prolog sources.
3 It is build as part of SWI-Prolog. See
4 http://www.swi-prolog.org/build/index.txt for building SWI-Prolog and
5 xpce.
6
7 The documentation below is in part out of date, but left as a reference.
8 Configuration, compilation and installation is based on the GNU autoconf
9 package.
10
11 ## Required tools
12
13 - GNU-Make
14 Non-gnu versions of make will fail.
15
16 - GCC or clang
17 Necessary on most machines, though you might get away with
18 another ANSI C compiler.
19
20 - libXpm
21 The X11 XPM (XPixMap) format libary for handling coloured and
22 masked images. For any popular Unix platform you should be
23 able to find this package. For the Windows built we provide
24 a port at https://github.com/SWI-Prolog/libXpm.git
25
26 - libjpeg
27 The JPEG group library for handling JPEG images.
28
29 - Freetype
30 Not really required, but if present the system will use the
31 Freetype library to realise scalable and antialiased fonts.
32 Its presence is detected by looking for the program xft-config,
33 which is also used to determine compile and link flags. If
34 you want to build WITHOUT XFT and you have the library installed,
35 set the environment variable XFTCONFIG=false.
36
37
38 For all other required tools, both the GNU, BSD and System-V versions
39 are supposed to work properly.
40
41 ## Bluffers Installation Guide
42
43 To install XPCE/SWI-Prolog from the sources:
44
45 1. Build SWI-Prolog according to the instructions and install it.
46 2. Determine an installation prefix (normally use the same as for
47 SWI-Prolog, we use `linux' in this example).
48 3. Run the following commands
49
50 % mkdir linux
51 % cd linux
52 % ../src/configure
53 % make
54 % make install
55
56 # Detailed Installation Guide
57
58 We start at the SWI-Prolog installation, as this needs some special
59 considerations on some platforms.
60
61
62 ## Choosing the build-directory
63
64 You can place the directory for building XPCE/Prolog anywhere. A good
65 choice is /usr/local/src or, if you are installing as a private user,
66 $HOME/src. Unpack the Prolog and XPCE archives from the same directory:
67
68 % gunzip < pl-<version>.tar.gz | tar xvfB -
69 % gunzip < xpce-<version>.tar.gz | tar xvfB -
70
71 NOTES:
72
73 - Some versions of tar hate reading from a pipe. In that case
74 use `gunzip file.tar.gz' followed by `tar xvf file.tar' to extract
75 the archives
76
77 - If you are using GNU-tar, `tar zxvf file.tar.gz' is easier.
78
79
80 ## Choosing a build sub-directory
81
82 For easy cleanup or building for multiple directories, both SWI-Prolog
83 and XPCE are normally built in a directory next to the src directory.
84 The name is not important. Good examples are `sunos' `linux', etc. In
85 the examples below, we use `linux'.
86
87
88 ## The Destination Prefix (configure --prefix=dir)
89
90 GNU autoconf-based packages accept the flag --prefix=<dir> to specify
91 the destination. The installation will use the following subdirectories:
92
93 ```
94 bin For making *links* to the executables
95 man/man1 For installing the manual pages
96 include For installing the SWI-Prolog.h header file
97 lib/pl-<version> For installing libs, executables, etc.
98 lib For installing public shared objects (if any)
99 ```
100
101 The default prefix is /usr/local. If you choose another one (assume
102 /home/projects/bigmoney), do (if the directory structure is not yet
103 available):
104
105 % cd /home/projects/bigmoney
106 % mkdir bin man man/man1 include lib
107
108 Make sure the binary directory is in your PATH!
109
110 ## Preparing SWI-Prolog
111
112 % cd pl-<version>
113 % mkdir linux
114 % cd linux
115 % ../src/configure
116
117 ## Shared libraries or not?
118
119 By default, the installation atempts to build SWI-Prolog and load xpce
120 as a shared object (.so file on most Unix machines) into Prolog. This
121 installation is better to maintain and prepares SWI-Prolog for loading
122 custom extensions written in C in a well supported manner.
123
124 Now, shared libraries are used on all systems and the the static
125 alternative is no longer actively maintained. When porting to a new OS,
126 please check the shared library facilities of the SWI-Prolog plld tool
127 and make sure it runs on your environment.
128
129 ## Preparing XPCE
130
131 XPCE extracts most information about the configuration from SWI-Prolog,
132 so it is generally much easier. Most of the configure run is simple, but
133 configure needs to find out where the X11 libraries and include files
134 are and you may have multiple. Normally, it will first try
135 /usr/include/X11 and /usr/lib. If you have only one version of X11
136 around, generally configure will be able to find it.
137
138 If you have multiple copies of X11 around, you have to decide which to
139 use. If you are compiling for local usage, use the one most of your
140 local packages use to improve resource sharing. Otherwise, use the one
141 distributed with the OS or known to be most commonly in use by your user
142 community. For example, our system has the MIT X11R6 libs and includes
143 in /usr/lib and /usr/include/X11 and the OpenWindows versions in
144 /usr/openwin/lib and /usr/openwin/include/X11. For local usage, we
145 configure without options to use the X11R6 version, used by most of the
146 other X11 software we run locally. For distribution, we configure using:
147
148 --x-includes=/usr/openwin/include --x-libraries=/usr/openwin/lib
149
150 ## Checking Program versions
151
152 Just to make sure your programs are accessible and of the right version,
153 try:
154
155 % swipl -v
156 SWI-Prolog version 5.3.9 for i686-linux
157 % make -v
158 GNU Make 3.80
159 ...
160 % gcc -v
161 gcc -v
162 Reading specs from /usr/lib/gcc-lib/i586-suse-linux/3.3.1/specs
163 ...
164 gcc version 3.3.1 (SuSE Linux)
165
166 Now, run configure:
167
168 % cd xpce-<version>
169 % mkdir linux
170 % ../src/configure <options>
171
172 ## Building the library
173
174 Now, make the XPCE library:
175
176 % make xpce
177
178 If you have configured for using shared libraries, the -fPIC flag should
179 be passed to the compiler. If this is not the case, please look closely
180 at the steps above. If all goes well, the compilation should finish with
181 few warnings, resulting in the library libXPCE.a
182
183
184 ## Building the interface:
185
186 With write premission to the Prolog home directory, now do the following
187 to make the interface.
188
189 % make pl-itf
190
191 This command will run either `make pl-shared' or `make pl-static',
192 depending on whether SWI-Prolog handles shared objects. The first builds
193 the pl2xpce.so shared object, and the second builds an XPCE executable
194 holding both the Prolog kernel and the XPCE library called `xpce'.
195
196 Both versions will put various things in the SWI-Prolog home directory
197 to make XPCE known to Prolog:
198
199 * A link to the xpce build-directory
200 * A swipl.rc script to register the xpce library
201 * A Makefile to recompile the XPCE/Prolog quick-load-files
202
203 ## Testing XPCE
204
205 Now, if you have build for a shared object, xpce is a dynamically
206 loadable Prolog library, so to test it simply do:
207
208 % swipl
209 ?- manpce.
210
211 which should start the manual tools.
212
213 ## Installing the XPCE library
214
215 Finally, to install the XPCE libraries, do:
216
217 % make install
218
219 Which will:
220
221 - Create a directory xpce-<version> in the Prolog home and
222 copy the Prolog libraries, manual data and other resources
223 into this directory.
224
225 - In the Prolog home, make a link from xpce to xpce-<version>
226
227 - run `make' in the Prolog home directory to make quick-load
228 versions of some large and frequently used library packages.
229
230 - in $exec_prefix/bin, make links to the xpce and xpce-client
231 executables
192192 javascript_mode.pl language_mode.pl latex_mode.pl logtalk_mode.pl
193193 man_mode.pl outline_mode.pl prolog_mode.pl prompt.pl rdf_mode.pl
194194 script_mode.pl server.pl sgml_mode.pl shell.pl swi_prolog.pl
195 text_mode.pl turtle_mode.pl window.pl yaml_mode.pl cmake_mode.pl)
195 text_mode.pl turtle_mode.pl window.pl yaml_mode.pl cmake_mode.pl
196 help_buffer.pl)
196197
197198 set(XPCE_DATA_prolog_lib_english pce_messages.pl)
198199
385386 set(XPCE_QLF_emacs emacs/window.pl emacs/buffer.pl emacs/application.pl
386387 emacs/buffer_menu.pl emacs/server.pl emacs/history.pl
387388 emacs/fundamental_mode.pl emacs/language_mode.pl emacs/outline_mode.pl
388 emacs/bookmarks.pl)
389 emacs/bookmarks.pl emacs/help_buffer.pl)
+0
-238
packages/xpce/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
+0
-45
packages/xpce/newversion less more
0 #!/bin/sh
1
2 function confirm ()
3 { while true; do
4 echo -n "$1 "
5 read answer
6 case "$answer" in
7 y*) return 0
8 ;;
9 n*) return 1
10 ;;
11 *)
12 echo "Please answer yes or no"
13 ;;
14 esac
15 done
16 }
17
18 version=`cat VERSION`
19 versiondate=`date +"%B %Y"`
20 major=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\1/'`
21 minor=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\2/'`
22 patch=`echo $version | sed 's/\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\)/\3/'`
23
24 tmp=.tmp$$
25
26 f=src/Makefile.in
27 sed "s/^PCEVERSIONDATE=.*/PCEVERSIONDATE=$versiondate/" $f > $tmp
28 if cmp $f $tmp; then
29 rm -f $tmp
30 else
31 cp $tmp $f
32 echo "Updated PCEVERSIONDATE in $f"
33 fi
34
35 f=src/h/interface.h
36 sed "s/^#define PCE_VERSION.*/#define PCE_VERSION "\""$version, $versiondate"\"/ $f > $tmp
37 if cmp $f $tmp; then
38 rm -f $tmp
39 else
40 cp $tmp $f
41 echo "Updated #define PCE_VERSION in $f"
42 fi
43
44 rm -f $tmp
22 Author: Jan Wielemaker and Anjo Anjewierden
33 E-mail: jan@swi.psy.uva.nl
44 WWW: http://www.swi.psy.uva.nl/projects/xpce/
5 Copyright (c) 2000-2011, University of Amsterdam
5 Copyright (c) 2000-2020, University of Amsterdam
66 All rights reserved.
77
88 Redistribution and use in source and binary forms, with or without
103103 @br
104104 ].
105105 element(div, A, C) --> % <DIV>
106 element(p, A, C). % TBD: Should force clearance of
106 element(p, A, C). % TBD: Should force clearance of
107 element(span, _, C) -->
108 seq(C).
107109 % shape-graphicals!
108110 element(br, _, _) --> % <BR>
109111 [ @br,
325327 ]
326328 ).
327329 element(a, Attr, Content) --> % <A NAME=<Label>> ... </A>
328 { memberchk(name=Label, Attr)
330 { memberchk(id=Label, Attr)
331 ; memberchk(name=Label, Attr)
329332 },
330333 !,
331334 [ \anchor(Label, Content)
359362 % Preformatted output
360363
361364 element(pre, _, Content) --> % <PRE>
362 [ @br,
365 [ \parskip,
363366 \group([ \setfont(fixed, @on),
364367 \pre(Content)
365368 ]),
380383 element(meta, _, _) --> % <META>
381384 [].
382385 element(link, _, _) --> % <LINK>
386 [].
387 element(script, _, _) --> % <SCRIPT>
383388 [].
384389 element(body, Attributes, Content) --> % <BODY>
385390 [ \body(Attributes)
538543 catch(number_chars(Num, Chars), _, fail),
539544 Frac is Num/100.
540545
546 seq([]) --> [].
547 seq([H|T]) --> [H], seq(T).
548
541549 /*******************************
542550 * MESSAGES *
543551 *******************************/
5050
5151 :- pce_begin_class(emacs, application,
5252 "PceEmacs main object").
53
54 class_variable(icon_image, image*, @pce_image).
5355
5456 variable(buffer_list, dict, get, "List of buffers maintained").
5557 variable(history, history, get, "History of visited places").
8686 :- consult(language_mode).
8787 :- consult(outline_mode).
8888 :- consult(bookmarks).
89 :- consult(help_buffer).
8990
9091
9192 /*******************************
0 /* Part of XPCE --- The SWI-Prolog GUI toolkit
1
2 Author: Jan Wielemaker
3 E-mail: J.Wielemaker@vu.nl
4 WWW: http://www.swi-prolog.org
5 Copyright (c) 2020, VU University Amsterdam
6 CWI, Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 :- module(emacs_show_help, []).
36 :- use_module(library(pce), [new/2, pce_open/3, send/2, op(_,_,_)]).
37 :- autoload(library(sgml), [load_html/3]).
38 :- autoload(library(lynx/html_text),[html_text/2]).
39 :- autoload(library(pce_emacs), [start_emacs/0]).
40
41 /** <module> Capture help in a PceEmacs buffer
42
43 This module captures the output of _Documentation_ in the PceEmacs
44 buffer ``*Documentation*``.
45
46 @tbd We should made the output of html_text/2 interceptable at a
47 higher level of abstraction such that we can create nice
48 coloured fragments.
49 */
50
51 :- multifile
52 prolog_help:show_html_hook/1.
53
54 prolog_help:show_html_hook(HTMLString) :-
55 thread_self(pce),
56 start_emacs,
57 send(@emacs, location_history),
58 setup_call_cleanup(
59 open_string(HTMLString, In),
60 load_html(stream(In), DOM, []),
61 close(In)),
62 new(B, emacs_buffer(@nil, '*Documentation*')),
63 send(B, mode, text),
64 send(B, clear),
65 setup_call_cleanup(
66 pce_open(B, write, Out),
67 ( set_stream(Out, newline(posix)),
68 with_output_to(Out, html_text(DOM, []))
69 ),
70 close(Out)),
71 send(B, modified, @off),
72 ( send(B?editors, empty)
73 -> send(B, open, tab)
74 ; send(B?editors, for_all, message(@arg1, caret, 0)),
75 get(B?editors?head, frame, Frame),
76 send(Frame, tab, B, @on),
77 send(Frame, expose)
78 ),
79 send(@emacs, location_history, title := 'Documentation').
80
81
82
5252 delete_breakpoint/1,
5353 manpce/1,
5454 prolog_ide/1,
55 rational/1,
5556 spypce/1,
56 trace/1,
5757 tracepce/1,
5858 atomic_list_concat/2,
5959 breakpoint_property/2,
6464 set_stream/2,
6565 source_file_property/2,
6666 string_codes/2,
67 term_string/2,
6768 term_to_atom/2,
6869 absolute_file_name/3,
6970 atomic_list_concat/3,
7071 between/3,
7172 compound_name_arity/3,
7273 default/3,
74 file_autoload_directives/3,
7375 file_name_extension/3,
7476 get_dict/3,
7577 nb_setarg/3,
78 rational/3,
7679 send_list/3,
7780 setup_call_cleanup/3,
81 stream_position_data/3,
7882 strip_module/3,
7983 xref_prolog_flag/4,
84 get_dict/5,
8085 sub_string/5
8186 ]).
8287
111116 view_threads = button(prolog),
112117 view_debug_messages = button(prolog),
113118 - = button(prolog),
119 check_dependencies = button(prolog),
120 update_dependencies = key('\\C-c\\C-d') + button(prolog),
114121 check_clause = key('\\C-c\\C-s') + button(prolog),
115122 setup_auto_indent = button(prolog),
116123 insert_full_stop = key(.),
171178 typing).
172179 class_variable(auto_colourise_size_limit, int, 100000,
173180 "Auto-colourise if buffer is smaller then this").
181 class_variable(dependency_directive,
182 { 'autoload/1',
183 'autoload/2',
184 'use_module/1',
185 'use_module/2'
186 }, 'autoload/2',
187 "How to insert new dependencies").
174188
175189 variable(varmark_style, style*, get, "How to mark variables").
176190 variable(has_var_marks, bool := @off, get, "Optimise a bit").
186200 variable(cond_indentation, int, get, "Indent step for conditional").
187201 variable(quasiquotation_syntax,
188202 name*, both, "Default quasiquotation syntax").
203 variable(dependency_directive,
204 { 'autoload/1',
205 'autoload/2',
206 'use_module/1',
207 'use_module/2'
208 },
209 both,
210 "How to insert new dependencies").
189211
190212 class_variable(quasiquotation_syntax, name*, @nil).
191213 class_variable(body_indentation, int, 4).
192214 class_variable(cond_indentation, int, 4).
193215 class_variable(indent_tabs, bool, @off,
194216 "Use tabs for indentation").
195
196217
197218 icon(_, I:image) :<-
198219 "Return icon for mode"::
890911 "Consult selected text"::
891912 get(M, selection, point(From, To)),
892913 send(M, consult_region, From, To).
914
915
916 /*******************************
917 * DEPENDENCIES *
918 *******************************/
919
920 :- meta_predicate
921 to_kill_buffer(0).
922
923 check_dependencies(E) :->
924 "See whether any dependencies are missing"::
925 get(E, text_buffer, TB),
926 file_autoload_directives(TB, Directives, [missing(true)]),
927 count_dependencies(Directives, Count),
928 ( Directives == []
929 -> send(E, report, status, 'No missing dependencies')
930 ; to_kill_buffer(maplist(portray_clause, Directives)),
931 send(E, report, warning,
932 'WARNING: %d missing dependencies. \c
933 Use ^Y to insert required directives at caret.',
934 Count)
935 ).
936
937 insert_dependencies(E) :->
938 "Insert :- autoload/2 directives"::
939 ( get(E, mark_status, active)
940 -> get(E, selection, point(From, To))
941 ; From = 0,
942 To = 0
943 ),
944 update_dependencies(E, From, To).
945
946 update_dependencies(E) :->
947 "Update existing dependencies or add new block"::
948 get(E, find_dependencies, point(From, To)),
949 update_dependencies(E, From, To).
950
951 update_dependencies(E, From, To) :-
952 read_terms_in_range(E, From, To, Terms),
953 directive_options(E, Terms, DirOptions),
954 get(E, text_buffer, TB),
955 file_autoload_directives(TB, Directives, [update(Terms)|DirOptions]),
956 ( append(Terms, New, Directives)
957 -> ( New == []
958 -> send(E, report, status, 'No updates required')
959 ; add_new_dependencies(E, New, To),
960 count_dependencies(New, Count),
961 send(E, report, status, 'Added %d new dependencies', Count)
962 )
963 ; send(E, delete, From, To),
964 add_new_dependencies(E, Directives, From),
965 send(E, report, status, 'Updated dependencies')
966 ).
967
968 add_new_dependencies(E, Directives, At) :-
969 send(@emacs, location_history),
970 send(E, caret, At),
971 send(@emacs, location_history, title := 'Update dependencies'),
972 setup_call_cleanup(
973 pce_open(E, update, Out),
974 ( seek(Out, At, bof, _),
975 with_output_to(Out, maplist(portray_clause, Directives))
976 ),
977 close(Out)),
978 get(E, caret, End),
979 send(E, selection, At, End, highlight),
980 send(E, auto_colourise_buffer).
981
982 directive_options(_E, Terms, []) :-
983 member(:-(Directive), Terms),
984 is_dependency(Directive),
985 !.
986 directive_options(E, _, [directive(Pred)]) :-
987 get(E, dependency_directive, Atom),
988 term_string(Pred, Atom).
989
990 count_dependencies(Directives, Deps) :-
991 maplist(directive_deps, Directives, Counts),
992 sum_list(Counts, Deps).
993
994 directive_deps((:- autoload(_, Preds)), Count) :-
995 !,
996 length(Preds, Count).
997 directive_deps((:- use_module(_, Preds)), Count) :-
998 !,
999 length(Preds, Count).
1000 directive_deps(_, 1).
1001
1002 to_kill_buffer(Goal) :-
1003 new(E, editor),
1004 setup_call_cleanup(
1005 pce_open(E, write, Out),
1006 with_output_to(Out, Goal),
1007 close(Out)),
1008 get(E?text_buffer, size, Size),
1009 send(E, grab, 0, Size),
1010 free(E).
1011
1012 read_selection(E, Terms:prolog) :<-
1013 "Read the selection as a list of terms"::
1014 get(E, selection, point(From, To)),
1015 read_terms_in_range(E, From, To, Terms).
1016
1017 read_terms_in_range(E, From, To, Terms) :-
1018 To > From,
1019 !,
1020 setup_call_cleanup(
1021 pce_open(E, read, In),
1022 ( seek(In, From, bof, _),
1023 read_terms_to(In, To, Terms)
1024 ),
1025 close(In)).
1026 read_terms_in_range(_, _, _, []).
1027
1028 read_terms_to(In, End, Terms) :-
1029 quiet_read_next(In, Term, _, Here),
1030 !,
1031 ( Term == end_of_file
1032 -> Terms = []
1033 ; ( Here > End
1034 -> Terms = []
1035 ; Terms = [Term|Rest],
1036 read_terms_to(In, End, Rest)
1037 )
1038 ).
1039 read_terms_to(_, _, []).
1040
1041 find_dependencies(E, Range:point) :<-
1042 "Get start and end of dependencies"::
1043 setup_call_cleanup(
1044 pce_open(E, read, In),
1045 find_dependencies(In, #{}, Dict),
1046 close(In)),
1047 get(E, text_buffer, TB),
1048 ( _{start:Start, end:End0} :< Dict
1049 -> get(TB, scan, End0, line, 1, start, End),
1050 new(Range, point(Start, End))
1051 ; _{module_decl_end:Start0} :< Dict
1052 -> get(TB, scan, Start0, line, 1, start, Start),
1053 new(Range, point(Start, Start))
1054 ; _{program_start:Start0} :< Dict
1055 -> get(TB, scan, Start0, line, -1, start, Start),
1056 new(Range, point(Start, Start))
1057 ).
1058
1059 find_dependencies(In, State0, State) :-
1060 quiet_read_next(In, Term, F, T),
1061 ( Term = :-(Directive)
1062 -> update_dep_state(Directive, F, T, State0, State1),
1063 find_dependencies(In, State1, State)
1064 ; State = State0.put(program_start, F)
1065 ).
1066
1067 update_dep_state(module(_,_), _, T, State0, State) :-
1068 !,
1069 State = State0.put(module_decl_end, T).
1070 update_dep_state(Decl, S, E, State0, State) :-
1071 is_dependency(Decl),
1072 !,
1073 ( get_dict(end, State0, _, State, E)
1074 -> true
1075 ; State = State0.put(#{start:S, end:E})
1076 ).
1077 update_dep_state(_, _, _, State, State).
1078
1079 is_dependency(autoload(_)).
1080 is_dependency(use_module(_)).
1081 is_dependency(autoload(_,_)).
1082 is_dependency(use_module(_,_)).
1083
1084 quiet_read_next(In, Term, From, To) :-
1085 between(1, 10, _),
1086 read_term(In, Term,
1087 [ syntax_errors(quiet),
1088 term_position(Pos)
1089 ]),
1090 nonvar(Term),
1091 stream_position_data(char_count, Pos, From),
1092 character_count(In, To),
1093 !.
8931094
8941095
8951096 /*******************************
15461546 *******************************/
15471547
15481548 location_history(M, Start:start=[int], Len:length=[int],
1549 Title:title=[char_array]) :->
1549 Always:always=[bool], Title:title=[char_array]) :->
15501550 "Add location to the editor history"::
15511551 ( Start == @default
15521552 -> get(M, caret, Caret),
15531553 get(M, scan, Caret, line, 0, start, SOF)
15541554 ; SOF = Start
15551555 ),
1556 ( send(M, history_not_interesting, SOF)
1556 ( Always \== @on,
1557 send(M, history_not_interesting, SOF)
15571558 -> true
15581559 ; get(M, text_buffer, TB),
15591560 new(_, emacs_history_fragment(TB, SOF, Len, Title))
+0
-41
packages/xpce/src/AGENDA less more
0 XPCE Agenda
1
2
3 TO DO:
4 *) Selection Service interaction (not only cut-buffers)
5 *) Editor/Text
6 1) Multi Kills backward: buggy
7 2) Handle non-printable characters correctly
8 *) Bitmaps:
9 1) Scaling
10 2) Stencils
11 *) `Resizer' object: inverted box to avoid redisplay
12 1) ->object: Graphical*
13 2) ->active: Boolean
14 3) ->execute: move attached object
15 *) Creating new expression classes?
16 *) NAME_forwards AND NAME_forward!!
17 *) Window ->grab_keyboard werkt niet zonder Window ->grab_pointer!
18 *) list_browser, editor: subclass of dialog_item?
19 *) Efficient constraint handling for spatials
20 1) Trap updates for spatials at class graphical?
21 *) Communicate with host on CWD (current directory)
22 *) Clone/save:
23 3) Relations (connection, constraint, hyper):
24 - Internal <-> external relations
25 *) Creation: exploit `variable <-initial_value' (also function)
26 Integrate with resource system. Part of `object ->initialise'?
27 *) Improve consistency of groups
28 *) Print \t as space for xwn-draw.c text functions
29 *) Add ->report: progress and ->report: done
30
31 Multi-Screen access
32
33 *) Resolve logical-font names.
34 *) Handling destruction of visual tool
35 *) Fix bitmaps
36 *) Resolve CurrentDisplay usage;
37 1) Display of current-event?
38 2) DisplayManager <- current
39 3) Display of some graphical
40 *) Display <->class --> resource_class
+0
-22
packages/xpce/src/CheckCommon less more
0 #!/bin/sh
1 #
2 # Check for symbols defined as COMMON and appearing in the global symbol
3 # table. This indicates that the COMMON definition is not visible when
4 # the function is defined, which causes errors on some linkers (Linux on
5 # IA_64 is one of them).
6 #
7 # Note: this script only works on Linux/i386. No worries, its only for
8 # me to find all such problems.
9
10 grep -w COMMON */*.h | \
11 sed 's/.*COMMON([^)]*)[ ]\([a-zA-Z_0-9]*\).*/\1/' | \
12 sort -u > Common.def
13
14 nm ../linux/pl2xpce.so | \
15 grep -w T | \
16 sed 's/.* T //' | \
17 sort -u > Common.glb
18
19 comm -12 Common.def Common.glb
20
21 rm -f Common.def Common.glb
+0
-30
packages/xpce/src/Makefile.def less more
0 .NOCHECK
1
2 ARCH=pc
3 OS=windows3.1
4 VERSION=4.8.5, Dec. 1994
5
6 MAKE=wmake /h
7 CC=wcc386
8 CXX=wpp386
9 CWFLAGS=
10 COFLAGS=/d1
11 CIFLAGS=-I.. -I..\..\..
12 CMFLAGS=-fpc -bt=windows
13 CFLAGS=$(CWFLAGS) $(COFLAGS) $(CIFLAGS) $(CMFLAGS)
14 LD=wlink
15 #LDFLAGS=system win386 debug all
16 LDFLAGS=system win386
17 WST=msw
18
19 LN=copy
20
21 MKPROTO=mkproto -p
22 CLPROTO=grep -vw NewClass
23 ETAGS=etags
24
25 .c.obj:
26 $(CC) /zq $(CFLAGS) $*.c
27
28 .cxx.obj
29 $(CXX) /zq $(CFLAGS) $*.cxx
+0
-8
packages/xpce/src/PROBLEMS less more
0
1 * Make the window border-line an X-window border
2 * Merge displacements of windows with updateConnectionsGraphical()
3 * Find a solution for ->display: Picture: should display the
4 <-decoration rather than the window itself.
5 * Make sure the move- and resize-gestures can be attached to
6 windows.
7 * Update documentation
+0
-40
packages/xpce/src/TODO less more
0 XPCE TODO List
1
2 [Badly maintained]
3
4 Frames and Windows
5 ==================
6
7 One of the annoying things at the moment is that frames are no windows
8 and therefore can be nested nor embedded in other XPCE GUI stuff. I
9 propose to make class frame a subclass of class Window, providing tiled
10 layout of subwindows. Other things that gets closer with this are MDI
11 and `docking' as windows can be re-parented more easily.
12
13 The other toplevel (shell-widget) code of class Frame can be integrated
14 in class Window. Steps:
15
16 * Create class frame_window below window and move the client-side
17 (tile) stuff there.
18
19 * Move relevant frame behaviour to class window.
20
21 * Remove class frame and rename frame_window to frame.
22
23 Consequences:
24
25 * Simple windows (no tiled) that are ->open'ed no longer have an
26 associated frame.
27
28 * <-frame will need an extra argument to indicate the desired frame
29 as frames are now nested.
30
31 Text handling
32 =============
33
34 The use of LocalString() can cause problems. Errors from alloca() are
35 non-portable and some systems have severe limits on what you can do with
36 alloca().
37
38
39
+0
-61
packages/xpce/src/TODO.MT less more
0 Multi-threading XPCE
1
2 Message Passing
3 ===============
4
5 * Move global-data to thread-local data. These are the 3 variables defined
6 in trace.h. Simple
7
8
9 Program objects
10 ===============
11
12 * Simplest: lock resolveImplementationGoal()
13 drawback: executes obtainers and other potentionally expensive code that
14 need not lock
15
16 * Alternative:
17 Lock class-access methods:
18 getSendMethodClass()
19 getGetMethodClass()
20 Also manipulation methods on same lock:
21 realising/method adding operations
22
23 Graphics
24 ========
25
26 Make state maintained by xdraw.c and msdraw.c thread-safe. Options:
27
28 * Lock d_*() ... d_done() sequences
29
30 * Use thread-local-data graphical resources
31
32 * Make changedWindow() and display-manipulation thread-safe.
33
34
35 User objects
36 ============
37
38 * Lock at the window level while changes are pending:
39 When changing a graphical, grab the window-mutex.
40
41 * GrabWindow
42 * Window is released after it is updated and repainted (i.e. ->flush)
43
44 * User objects:
45
46 + leave to user (simple)
47 + Provide basic security on data objects (chains, vector, table)
48
49 - `ForAll' can take long and risks deadlocks!
50
51 + Allow objects to have a mutex associated?
52
53 - send(Obj, mutex, {write,all,none})
54 - write: lock sends to this object
55 - read: lock all
56
57 Work-threads
58 ============
59
60
+0
-36
packages/xpce/src/TODO.win less more
0 MS-Windows Port TODO List
1 Jan Wielemaker
2
3 % Last updated: Fri Mar 19 1999
4
5 Images:
6
7 * TBD: Save in MS-Windows format
8
9 Timers:
10
11 * FIX: Sometimes stops after closing some window.
12 * TBD: Implement timers with a time of > 2**16 milliseconds.
13
14 GUI:
15
16 * Uwe Lesta:
17
18 `` If you like i can tell you some things
19 where the use of the dialog elements
20 can be make more elegant (windows like).
21 e.g. a combobox ( a text_item with a value_set )
22 on windows you can also select a value by open the box
23 and drag down to the value you want.
24 Or an other example your list browser e.g.
25 Demo programs. I open it select the Program (all with the keyboard)
26 that i like and than ?? I need the mouse.
27 with which key can i open it. ?
28 (Alt+O don't work, but the selecton is green not blue)
29 ''
30
31 BUGS:
32
33 * new(X, colour('#00ffff')) fails.
34 * drawing boxes of very small size fails (see remark in msdraw.c).
35 * Symbol-font not mounted correctly
+0
-127
packages/xpce/src/aclocal.m4 less more
0 dnl SWI-Prolog specific autoconf macros
1
2 dnl Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009 Free Software
3 dnl Foundation, Inc.
4 dnl Copyright 2011, Roberto Bagnara, BUGSENG srl.
5 dnl
6 dnl This file is part of SWI-Prolog.
7 dnl
8 dnl This library is free software; you can redistribute it and/or modify
9 dnl it under the terms of the GNU Lesser General Public License as published
10 dnl by the Free Software Foundation; either version 3 of the License, or (at
11 dnl your option) any later version.
12 dnl
13 dnl This library is distributed in the hope that it will be useful, but
14 dnl WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 dnl or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 dnl License for more details.
17 dnl
18 dnl You should have received a copy of the GNU Lesser General Public License
19 dnl along with this library. If not, see http://www.gnu.org/licenses/.
20
21
22 dnl All the "FOR_BUILD" macros have been copied from the GNU MP Library
23 dnl and then slightly modified.
24
25
26 dnl SWI_PROG_CC_FOR_BUILD
27 dnl ---------------------
28 dnl Establish CC_FOR_BUILD, a C compiler for the build system.
29 dnl
30 dnl If CC_FOR_BUILD is set then it's expected to work, otherwise some
31 dnl likely candidates are tried.
32
33 AC_DEFUN([SWI_PROG_CC_FOR_BUILD],
34 [AC_REQUIRE([AC_PROG_CC])
35 if test -n "$CC_FOR_BUILD"; then
36 SWI_PROG_CC_FOR_BUILD_WORKS($CC_FOR_BUILD,,
37 [AC_MSG_ERROR([Specified CC_FOR_BUILD doesn't seem to work])])
38 else
39 for i in cc gcc clang c89 c99 "$CC" "$CC $CFLAGS $CPPFLAGS"; do
40 SWI_PROG_CC_FOR_BUILD_WORKS($i,
41 [CC_FOR_BUILD=$i
42 break])
43 done
44 if test -z "$CC_FOR_BUILD"; then
45 AC_MSG_ERROR([Cannot find a build system compiler])
46 fi
47 fi
48
49 AC_ARG_VAR(CC_FOR_BUILD,[build system C compiler])
50 AC_SUBST(CC_FOR_BUILD)
51 ])
52
53
54 dnl SWI_PROG_CC_FOR_BUILD_WORKS(cc/cflags[,[action-if-good][,action-if-bad]])
55 dnl -------------------------------------------------------------------------
56 dnl See if the given cc/cflags works on the build system.
57 dnl
58 dnl It seems easiest to just use the default compiler output, rather than
59 dnl figuring out the .exe or whatever at this stage.
60
61 AC_DEFUN([SWI_PROG_CC_FOR_BUILD_WORKS],
62 [AC_MSG_CHECKING([build system compiler $1])
63 # remove anything that might look like compiler output to our "||" expression
64 rm -f conftest* a.out b.out a.exe a_out.exe
65 cat >conftest.c <<EOF
66 int
67 main ()
68 {
69 exit(0);
70 }
71 EOF
72 swi_compile="$1 -DHAVE_CONFIG_H conftest.c"
73 cc_for_build_works=no
74 if AC_TRY_EVAL(swi_compile); then
75 if (./a.out || ./b.out || ./a.exe || ./a_out.exe || ./conftest) >&AC_FD_CC 2>&1; then
76 cc_for_build_works=yes
77 fi
78 fi
79 rm -f conftest* a.out b.out a.exe a_out.exe
80 AC_MSG_RESULT($cc_for_build_works)
81 if test "$cc_for_build_works" = yes; then
82 ifelse([$2],,:,[$2])
83 else
84 ifelse([$3],,:,[$3])
85 fi
86 ])
87
88
89 dnl SWI_PROG_EXEEXT_FOR_BUILD
90 dnl -------------------------
91 dnl Determine EXEEXT_FOR_BUILD, the build system executable suffix.
92 dnl
93 dnl The idea is to find what "-o conftest$foo" will make it possible to run
94 dnl the program with ./conftest. On Unix-like systems this is of course
95 dnl nothing, for DOS it's ".exe", or for a strange RISC OS foreign file
96 dnl system cross compile it can be ",ff8" apparently. Not sure if the
97 dnl latter actually applies to a build-system executable, maybe it doesn't,
98 dnl but it won't hurt to try.
99
100 AC_DEFUN([SWI_PROG_EXEEXT_FOR_BUILD],
101 [AC_REQUIRE([SWI_PROG_CC_FOR_BUILD])
102 AC_CACHE_CHECK([for build system executable suffix],
103 swi_cv_prog_exeext_for_build,
104 [cat >conftest.c <<EOF
105 int
106 main ()
107 {
108 exit (0);
109 }
110 EOF
111 for i in .exe ,ff8 ""; do
112 swi_compile="$CC_FOR_BUILD conftest.c -o conftest$i"
113 if AC_TRY_EVAL(swi_compile); then
114 if (./conftest) 2>&AC_FD_CC; then
115 swi_cv_prog_exeext_for_build=$i
116 break
117 fi
118 fi
119 done
120 rm -f conftest*
121 if test "${swi_cv_prog_exeext_for_build+set}" != set; then
122 AC_MSG_ERROR([Cannot determine executable suffix])
123 fi
124 ])
125 AC_SUBST(EXEEXT_FOR_BUILD,$swi_cv_prog_exeext_for_build)
126 ])
+0
-207
packages/xpce/src/bitmaps/pce16.xpm less more
0 /* XPM */
1 static char * pce16_xpm[] = {
2 "16 16 188 2",
3 " c None",
4 ". c #EE8B39",
5 "+ c #E93932",
6 "@ c #DA3533",
7 "# c #F39B38",
8 "$ c #F79E32",
9 "% c #F7A43C",
10 "& c #F69B37",
11 "* c #F58E2F",
12 "= c #F4832C",
13 "- c #F2752B",
14 "; c #EF6C30",
15 "> c #EF552B",
16 ", c #EF3322",
17 "' c #F6AD41",
18 ") c #FAB74E",
19 "! c #FAB64B",
20 "~ c #F8A633",
21 "{ c #F79B31",
22 "] c #F58D2F",
23 "^ c #F37C29",
24 "/ c #F27231",
25 "( c #F26D42",
26 "_ c #F04D36",
27 ": c #EA382C",
28 "< c #FBDAA2",
29 "[ c #FEEECF",
30 "} c #FFEDCC",
31 "| c #FCD28E",
32 "1 c #F8A437",
33 "2 c #F69231",
34 "3 c #F6964C",
35 "4 c #FAC5A7",
36 "5 c #FCDBCE",
37 "6 c #FBC3B9",
38 "7 c #F1817C",
39 "8 c #FBDDB3",
40 "9 c #FFFFFF",
41 "0 c #FAFCFF",
42 "a c #F6FAFE",
43 "b c #FEFFFF",
44 "c c #FAC681",
45 "d c #F79634",
46 "e c #FCE1CB",
47 "f c #FAFEFF",
48 "g c #F7FFFF",
49 "h c #FDEBEA",
50 "i c #DF7773",
51 "j c #F7B56C",
52 "k c #FEF1E0",
53 "l c #FBFDFF",
54 "m c #D9DADA",
55 "n c #787778",
56 "o c #C2C5C8",
57 "p c #FFEBD4",
58 "q c #FBA147",
59 "r c #F5F6F6",
60 "s c #BFC0C1",
61 "t c #878688",
62 "u c #D3DCDD",
63 "v c #E39090",
64 "w c #F5A353",
65 "x c #FFF4E9",
66 "y c #929294",
67 "z c #1C1819",
68 "A c #9C9C9E",
69 "B c #D7D5D1",
70 "C c #CBB6A2",
71 "D c #E7EAEC",
72 "E c #F4F4F4",
73 "F c #797879",
74 "G c #262224",
75 "H c #B9C0C2",
76 "I c #E08D8E",
77 "J c #B82828",
78 "K c #F48E39",
79 "L c #FBD0A7",
80 "M c #E3E4E5",
81 "N c #BEBFC1",
82 "O c #C8C9CC",
83 "P c #D1D3D3",
84 "Q c #D3D4D5",
85 "R c #B3B5B7",
86 "S c #F7F9F9",
87 "T c #DADBDC",
88 "U c #C1C3C4",
89 "V c #F1F6F5",
90 "W c #CD464A",
91 "X c #AC191B",
92 "Y c #F27B29",
93 "Z c #F5903F",
94 "` c #FCD4B5",
95 " . c #FFFCF9",
96 ".. c #FFFCF5",
97 "+. c #D6BBA7",
98 "@. c #BDBEBF",
99 "#. c #BFC0C2",
100 "$. c #A29A99",
101 "%. c #F7CEC0",
102 "&. c #FFFEFE",
103 "*. c #FEECEA",
104 "=. c #DE6A6B",
105 "-. c #B8151B",
106 ";. c #A21B1D",
107 ">. c #E66928",
108 ",. c #EA7227",
109 "'. c #EC7421",
110 "). c #F07D2D",
111 "!. c #F37A27",
112 "~. c #F17427",
113 "{. c #8D7C75",
114 "]. c #7C7D7F",
115 "^. c #B15C46",
116 "/. c #F53B19",
117 "(. c #EB2D25",
118 "_. c #D7151B",
119 ":. c #BD0D14",
120 "<. c #A70D12",
121 "[. c #931112",
122 "}. c #D35728",
123 "|. c #D1551D",
124 "1. c #CC581D",
125 "2. c #DD6022",
126 "3. c #ED6727",
127 "4. c #F46326",
128 "5. c #C65C35",
129 "6. c #785954",
130 "7. c #F14024",
131 "8. c #ED2B24",
132 "9. c #D7181E",
133 "0. c #B71016",
134 "a. c #9E0B0F",
135 "b. c #850406",
136 "c. c #8C1613",
137 "d. c #DF5132",
138 "e. c #D7451D",
139 "f. c #DB4C20",
140 "g. c #E75123",
141 "h. c #F05326",
142 "i. c #F04E26",
143 "j. c #F34523",
144 "k. c #D04034",
145 "l. c #ED2622",
146 "m. c #E01B22",
147 "n. c #C8161C",
148 "o. c #AD1015",
149 "p. c #98090C",
150 "q. c #820405",
151 "r. c #CF2A1D",
152 "s. c #DE321F",
153 "t. c #EF3823",
154 "u. c #F23422",
155 "v. c #EF2F24",
156 "w. c #EC2824",
157 "x. c #E72022",
158 "y. c #D91920",
159 "z. c #C9141A",
160 "A. c #B81016",
161 "B. c #9E0A0E",
162 "C. c #840305",
163 "D. c #740303",
164 "E. c #D31E22",
165 "F. c #E02124",
166 "G. c #DD2527",
167 "H. c #CD3133",
168 "I. c #D81E23",
169 "J. c #D7181F",
170 "K. c #CB161E",
171 "L. c #C01319",
172 "M. c #A72024",
173 "N. c #99181B",
174 "O. c #910406",
175 "P. c #7A0001",
176 "Q. c #6F0202",
177 "R. c #9C8489",
178 "S. c #B6A9AC",
179 "T. c #A08384",
180 "U. c #B51E25",
181 "V. c #B51319",
182 "W. c #994649",
183 "X. c #ABA3A6",
184 "Y. c #A4979A",
185 "Z. c #97999C",
186 "`. c #A0A2A4",
187 " + c #7B7B7F",
188 ".+ c #C4C7CA",
189 "++ c #ACAFB1",
190 "@+ c #888A8C",
191 " . + @ ",
192 " # $ % & * = - ; > , ",
193 " ' ) ! ~ { ] ^ / ( _ : ",
194 " < [ } | 1 2 3 4 5 6 7 ",
195 " 8 9 0 a b c d e 9 f g h i ",
196 " j k l m n o p q 9 r s t u v ",
197 " w x l y z A B C D E F G H I J ",
198 " K L 9 M N O P Q R S T U V W X ",
199 " Y Z ` ...+.@.#.$.%.&.*.=.-.;.",
200 " >.,.'.).!.~.{.].^./.(._.:.<.[.",
201 " }.|.1.2.3.4.5.6.7.8.9.0.a.b.c.",
202 " d.e.f.g.h.i.j.k.l.m.n.o.p.q. ",
203 " r.s.t.u.v.w.x.y.z.A.B.C.D. ",
204 " E.F.G.H.I.J.K.L.M.N.O.P.Q. ",
205 " R.S.T.U.V.W.X.Y. ",
206 " Z. `. +.+++@+ "};
0 /* XPM */
1 static char *swipl48_xpm[] = {
2 /* columns rows colors chars-per-pixel */
3 "48 48 225 2 ",
4 " c #231F20",
5 ". c #6A0B0E",
6 "X c #730B0E",
7 "o c #770E11",
8 "O c #6D0C10",
9 "+ c #691928",
10 "@ c #49243A",
11 "# c #403E3F",
12 "$ c #591D2F",
13 "% c #092C49",
14 "& c #17314C",
15 "* c #153352",
16 "= c #26384E",
17 "- c #293B51",
18 "; c #313E51",
19 ": c #163E64",
20 "> c #452840",
21 ", c #394557",
22 "< c #3C424F",
23 "1 c #1E446B",
24 "2 c #4C4A4A",
25 "3 c #454D5A",
26 "4 c #575557",
27 "5 c #49515E",
28 "6 c #6D5054",
29 "7 c #4C5462",
30 "8 c #555B66",
31 "9 c #656364",
32 "0 c #67676C",
33 "q c #746869",
34 "w c #676A73",
35 "e c #6D7179",
36 "r c #74767A",
37 "t c #5C6069",
38 "y c #870E12",
39 "u c #930F14",
40 "i c #851013",
41 "p c #941115",
42 "a c #9D1116",
43 "s c #99161A",
44 "d c #A41217",
45 "f c #AC1419",
46 "g c #A41419",
47 "h c #B3141A",
48 "j c #BB151B",
49 "k c #BF181E",
50 "l c #B13519",
51 "z c #981C29",
52 "x c #963233",
53 "c c #AA242D",
54 "v c #A11C2A",
55 "b c #C3161C",
56 "n c #CC171E",
57 "m c #CB1C1F",
58 "M c #D5181F",
59 "N c #D0171E",
60 "B c #CD301E",
61 "V c #DC1920",
62 "C c #D41920",
63 "Z c #CD1921",
64 "A c #E31B22",
65 "S c #EB1C23",
66 "D c #D32C2F",
67 "F c #EE2323",
68 "G c #EE2C22",
69 "H c #E82624",
70 "J c #EF3422",
71 "K c #E83B23",
72 "L c #F03C21",
73 "P c #F03722",
74 "I c #EF3E3E",
75 "U c #DB4B1F",
76 "Y c #C4451C",
77 "T c #D4452F",
78 "R c #E94723",
79 "E c #F04421",
80 "W c #F14B21",
81 "Q c #E75621",
82 "! c #F15321",
83 "~ c #F25B21",
84 "^ c #EE463B",
85 "/ c #F36420",
86 "( c #F36C20",
87 ") c #F47421",
88 "_ c #F57B21",
89 "` c #EC6C35",
90 "' c #BC3957",
91 "] c #DB374A",
92 "[ c #824A49",
93 "{ c #A94C46",
94 "} c #9D506B",
95 "| c #BB5569",
96 " . c #866969",
97 ".. c #887A7A",
98 "X. c #956768",
99 "o. c #AF6667",
100 "O. c #CD4A45",
101 "+. c #EF4E49",
102 "@. c #F17053",
103 "#. c #D96A6E",
104 "$. c #E97875",
105 "%. c #C85678",
106 "&. c #F58321",
107 "*. c #F68B21",
108 "=. c #F69422",
109 "-. c #F79C22",
110 ";. c #F48537",
111 ":. c #F79838",
112 ">. c #F8A423",
113 ",. c #F8A923",
114 "<. c #BA877A",
115 "1. c #F58448",
116 "2. c #F58755",
117 "3. c #EA8459",
118 "4. c #F5AB4D",
119 "5. c #F19471",
120 "6. c #F3AA72",
121 "7. c #36629B",
122 "8. c #3D69A3",
123 "9. c #325D93",
124 "0. c #526896",
125 "q. c #787B83",
126 "w. c #6A7994",
127 "e. c #587CB3",
128 "r. c #4D6EA7",
129 "t. c #5E6594",
130 "y. c #B06E93",
131 "u. c #7C828F",
132 "i. c #6C8BBE",
133 "p. c #6383B8",
134 "a. c #718AB8",
135 "s. c #7888A9",
136 "d. c #5E80B5",
137 "f. c #7993C3",
138 "g. c #848384",
139 "h. c #8C8B8C",
140 "j. c #898787",
141 "k. c #958B8B",
142 "l. c #949293",
143 "z. c #9C9B9B",
144 "x. c #989799",
145 "c. c #8F8F92",
146 "v. c #A39F9F",
147 "b. c #B58F8F",
148 "n. c #8792AB",
149 "m. c #989BA3",
150 "M. c #8F94B5",
151 "N. c #A19FA0",
152 "B. c #BB9CB0",
153 "V. c #99A4BE",
154 "C. c #A4A3A3",
155 "Z. c #A9A6A6",
156 "A. c #AEADAD",
157 "S. c #A4A5AA",
158 "D. c #B0AFAF",
159 "F. c #B8A8A9",
160 "G. c #B3ACB3",
161 "H. c #B3B2B2",
162 "J. c #B8B7B7",
163 "K. c #BCBBBB",
164 "L. c #B6B6B9",
165 "P. c #A8ACB5",
166 "I. c #CA9697",
167 "U. c #D99292",
168 "Y. c #DD8588",
169 "T. c #E6938C",
170 "R. c #F5AA88",
171 "E. c #F6B78B",
172 "W. c #EEAA94",
173 "Q. c #C1BEBE",
174 "!. c #C5B4B5",
175 "~. c #D2B2B1",
176 "^. c #E5B8B9",
177 "/. c #EFB1A7",
178 "(. c #CE9A9A",
179 "). c #FAC48D",
180 "_. c #F9CDB3",
181 "`. c #849CC8",
182 "'. c #8BA2CC",
183 "]. c #99A7CA",
184 "[. c #98ABD2",
185 "{. c #A3AAC5",
186 "}. c #ACB3C3",
187 "|. c #BBBDC4",
188 " X c #AAB9D9",
189 ".X c #B2BDD8",
190 "XX c #C0BFC0",
191 "oX c #B7C2DC",
192 "OX c #BEC2CE",
193 "+X c #B9C5E1",
194 "@X c #BAC7E2",
195 "#X c #C4C3C4",
196 "$X c #CCCBCB",
197 "%X c #C6C6C8",
198 "&X c #D9CDCD",
199 "*X c #CCCED4",
200 "=X c #D4D3D3",
201 "-X c #DBDBDB",
202 ";X c #D7D7DA",
203 ":X c #D0D1D7",
204 ">X c #F9D7C9",
205 ",X c #E5DCDA",
206 "<X c #FBDBD6",
207 "1X c #EDCBCA",
208 "2X c #FDE8D7",
209 "3X c #C2CDE5",
210 "4X c #CBD4E9",
211 "5X c #CCD5EA",
212 "6X c #D4DCED",
213 "7X c #D9DCE7",
214 "8X c #DCE3F1",
215 "9X c #E4E4E4",
216 "0X c #ECEBEC",
217 "qX c #E4E5EA",
218 "wX c #FCEBE8",
219 "eX c #FCF2EC",
220 "rX c #E5EAF5",
221 "tX c #EAEDF6",
222 "yX c #E3E8F4",
223 "uX c #EEF2F9",
224 "iX c #F2F2F2",
225 "pX c #F3F6FB",
226 "aX c #FFFFFF",
227 "sX c #FBF5F5",
228 "dX c None",
229 /* pixels */
230 "dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX-X;X=X=X=X$X$X$X#XdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
231 "dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX9X9X9X-X-X-X;X;X=X=X=X$X%X#X#XXXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
232 "dXdXdXdXdXdXdXdXdXdXdXdXdXdX9X9X9X9X9X-X9X-X-X;X;X=X=X$X$X%X#XK.J.J.H.dXdXdXdXdXdXdXdXdXdXdXdXdX",
233 "dXdXdXdXdXdXdXdXdXdXdXdXqXqX9X9X*X|.}.].V.{.}.OX$X=X=X$X$X%X#XXXK.J.H.D.dXdXdXdXdXdXdXdXdXdXdXdX",
234 "dXdXdXdXdXdXdXdXdXdX0X0XqX*X}.f.i.p.p.d.e.e.r.r.r.s.L.%X$X$X%XXXQ.J.L.D.A.H.dXdXdXdXdXdXdXdXdXdX",
235 "dXdXdXdXdXdXdXdXdX0XqX:X[.'.`.f.f.f.p.p.d.p.s.n.n.d.0.w.A.$X$X%X#XK.J.H.A.A.D.dXdXdXdXdXdXdXdXdX",
236 "dXdXdXdXdXdXdXdX0XqXoX[.[.'.'.f.f.f.M.L.$X-X-X-X-X=X$XXXn.x.XX$X#XK.K.L.D.D.D.D.dXdXdXdXdXdXdXdX",
237 "dXdXdXdXdXdXdX0XqX.X XG.B.{.'.'.`.|.7XqX0X0X0X9X9X9X-X-X=X$XXX%X#X!.!.I.F.A.A.D.D.dXdXdXdXdXdXdX",
238 "dXdXdXdXdXdX0XqXoXoX XU.) _ 3.N.*X0XiXiXiX0X0X9X9X9X9X-X;X=X=X#X$.F S O.G.G.A.A.D.D.dXdXdXdXdXdX",
239 "dXdXdXdXdXiX0X3X@X@XoX.X;.&.&.&._.sXiX>X/.6.5.2.1.5.T./.&X-X^.^ G F S I.J.J.D.D.Z.D.D.dXdXdXdXdX",
240 "dXdXdXdX0X0X7X3X3X3X@X+X5.*.*.*.*.E.:.*.&.&._ _ ( ( ~ ~ ! $.+.E G F S !.J.D.D.D.x.C.D.D.dXdXdXdX",
241 "dXdXdXdXiXqX5X6X4X4X3X@XR.=.-.-.-.=.-.=.*.*.&._ _ ( / ~ ! W E L J F S !.K.J.D.D.Z.u.D.D.dXdXdXdX",
242 "dXdXdXiX0X7X6X6X6X5X4X3X6.-.>.>.>.,.>.-.=.=.*.&._ ( ( ~ ~ W E L J G F !.K.L.H.A.A.e N.D.D.dXdXdX",
243 "dXdXdXiXqX8XyX8X8X6X7X5X4.>.,.,.,.,.,.>.-.=.*.&._ ) ( / ~ ! W E J G F ~.K.L.H.D.D.h.r D.D.D.dXdX",
244 "dXdXiX0XrXtXtXrXrX8X6X&X>.).2XeXeX2X_.4.>.-.=.*.&._ ( / W.<X2XwX<X/.+.$.K.J.H.A.A.C.5 C.D.D.dXdX",
245 "dXdX0X0XuXuXuXuXtX8X7X6.wXaXaXaXaXaXaXeX).-.=.*.&._ 2.wXaXaXaXaXaXaXwX$.I.J.H.A.A.A.t h.D.D.dXdX",
246 "dXiX0X0XpXpXaXpXuXqXE.wXaXaXaXaXaXaXaXaXaXE.-.*.&.1.eXaXaXaXaXaXaXaXaXaX$.F.D.D.D.D.r 0 Z.D.H.dX",
247 "dX0X0XtXpXpXaXpXuX,X_.aXaXaXaXaXaXaXaXaXaXeX-.*.&.>XaXaXaXaXaXaXaXaXaXaX<X#.D.D.D.D.c., C.D.D.dX",
248 "dX0X0XtXpXpXpXpXuX6.sXaXaXaXaXiX=X%X=XiXaXaXE.*.1.aXaXaXaXaXiX=X#X=XiXaXaXY.b.D.A.A.m.% c.D.D.dX",
249 "dX0XqXtXpXpXpXuX>X6.aXaXaXaXsX%Xl.9 h.K.sXaX>X*.E.aXaXaXaXiXXXh.9 l.#XiXaX^.| D.D.A.Z.& r A.D.H.",
250 "dX0X9XyXrXtXtXtXW.E.aXaXaXaX9Xz.iXr x.-XaX2X*./.aXaXaXaX-Xz.pX4 N.9XaX1Xb Z.A.D.A., t A.D.H.",
251 "0X0X7XqXyXyXrXqX;.6.aXaXaXaX-Xl.2 j.=XaX&X(.~.iXaXaXaX=Xj.2 l.-XaX^.j y.A.D.A., 7 S.D.H.",
252 "9X0X7X7X8X8X8X&X_ ;.aXaXaXaX0XL.2 # H.-X#X%X$X#XA.9XaXaX9XH.# 2 H.0XaXU.j o.D.A.A.5 , C.D.D.",
253 "9X9X7X6X6X6X6X^._ _ >XaXaXaXaX-XJ.Z.J.=X%X%X-X-X$XJ.z.aXaXaX=XJ.A.K.;XaXiXD h { A.D.A., , z.D.D.",
254 "9X9X7X4X4X4X4XW.) ) 2.sXaXaXaXaXiXqX0XaXD.$X-X-X&XJ.c.qXaXaXaXiX0XiXaXpXU.j h g A.D.A.= - N.D.D.",
255 "9X9X;X@X@X3X3XU.( ( _ 5.eXaXaXaXaXaXaXaXC.Q.=X=X%XD.j.9XaXaXaXaXaXaXaXW.b j f a Z.D.C.% , N.D.H.",
256 "9X9X;X+X+X+X+XY./ ( ( ) 1._.eXaXaXsX,X5.<.Z.J.J.D.x. .@.1XeXaXaXsX1X#.n j h d a Z.D.l.% , C.D.H.",
257 "dX,X;X X X+X.XY.Q / / ( ( ( ( ` 2.) ) _ O.<.l.l.j.q T R G G +.+.S M m b j f a u Z.A.q.% 8 Z.D.H.",
258 "dX-X,X X X X X(.U ~ ~ / / ( / ( / / / / / { 9 9 4 [ L P G F F S V C n k f d u x D.A.5 % w A.D.dX",
259 "dX;X;X.X[.[.[.B.U l U U Q Q Q / ~ ~ ~ ! ! R 6 4 4 T P G F F S A C k h a d i o X.D.z.% % g.A.D.dX",
260 "dX-X7XXX'.[.[.[.E U W U l Q B Y Q ! ! W W E O.4 { J G G F S A j a k g i d p i k.D.w % = z.D.H.dX",
261 "dXdX;X:X'.'.'.`.#.K E R R W U R W E W E E L K [ K G F F S A M n f j h g a y i v.z.& % 8 Z.D.H.dX",
262 "dXdX=X;X{.`.f.`.y.B B K B K K E E L L L L J J D G F S S V M N n j f a p o O [ Z.7 % % h.A.A.dXdX",
263 "dXdX=X=X%Xa.f.f.M.J B P B l L J P P P J G G F F F F S V M n b j f p X p y X X.e % % 8 N.D.D.dXdX",
264 "dXdXdX$X=XV.i.i.f.] G G G J G G G G G G G F F S S A V M m b j h d d p y o o 6 % % & c.A.D.dXdXdX",
265 "dXdXdX$X$X#Xa.p.e.%.m Z H F F F F F F S S S S A V M n b b j f g a p y X . O & % % e Z.D.H.dXdXdX",
266 "dXdXdXdX%X$XP.d.e.y.M N A A A S S S S A A V V M N n b b h d g a p y i o . + % % 8 C.A.A.dXdXdXdX",
267 "dXdXdXdXdX%X%XM.e.w.V V ] | V A A D D V M M m b b j h d g v s i u + $ X . $ % 5 x.A.A.H.dXdXdXdX",
268 "dXdXdXdXdX#X#XK.y.r.M ' r.8.t.} ..c.h.X.D j k j h f v X.h.l.<.6 @ % % @ . @ 4 x.A.A.H.dXdXdXdXdX",
269 "dXdXdXdXdXdXQ.Q.|.f.} 8.8.7.0.g.A.|.K.N. .x c v v z q v.J.Q.S.u.2 % % % @ 9 z.A.A.A.dXdXdXdXdXdX",
270 "dXdXdXdXdXdXdXJ.L.L.m.0.7.9.0 m.OX=X=XJ.j., * % % & <.H.=X-X%XZ.0 % % , u.Z.A.A.D.dXdXdXdXdXdXdX",
271 "dXdXdXdXdXdXdXdXL.L.L.Z.c.9.9 C.S.u.u.C.c.3 % % % = u.Z.q.e m.Z.q < r z.Z.D.A.D.dXdXdXdXdXdXdXdX",
272 "dXdXdXdXdXdXdXdXdXL.D.H.D.C.9 q.1 : : * 0 < % % % < 0 - % % = r 9 z.A.A.A.A.H.dXdXdXdXdXdXdXdXdX",
273 "dXdXdXdXdXdXdXdXdXdXdXD.D.D.h.z.l.u.w 7 5 < & % & , 5 8 w j.x.C.g.D.A.A.A.H.dXdXdXdXdXdXdXdXdXdX",
274 "dXdXdXdXdXdXdXdXdXdXdXdXD.D.A.A.D.D.A.Z.C.N.z.z.z.N.C.Z.A.A.A.A.D.D.D.D.dXdXdXdXdXdXdXdXdXdXdXdX",
275 "dXdXdXdXdXdXdXdXdXdXdXdXdXdXH.D.D.D.D.D.D.D.H.D.D.D.D.D.D.D.A.D.D.D.dXdXdXdXdXdXdXdXdXdXdXdXdXdX",
276 "dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXH.H.D.D.D.D.D.D.D.D.D.D.D.H.L.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX",
277 "dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXH.H.H.H.H.H.dXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdXdX"
278 };
960960
961961
962962 #ifdef XPM_PCEIMAGE
963 #include "bitmaps/pce16.xpm"
963 #include "bitmaps/swipl48.xpm"
964964 #include "bitmaps/hadjusttile.xpm"
965965 #include "bitmaps/vadjusttile.xpm"
966966 #include "bitmaps/up.xpm"
10341034 stdImage(NAME_intItemImage, &INT_ITEM_IMAGE,
10351035 (char*)intarrows_bits, intarrows_width, intarrows_height);
10361036 #ifdef XPM_PCEIMAGE
1037 stdXPMImage(NAME_pceImage, NULL, pce16_xpm);
1037 stdXPMImage(NAME_pceImage, NULL, swipl48_xpm);
10381038 stdXPMImage(NAME_hadjustTileImage, NULL, hadjusttile_xpm);
10391039 stdXPMImage(NAME_vadjustTileImage, NULL, vadjusttile_xpm);
10401040 stdXPMImage(NAME_scrollUpImage, &SCROLL_UP_IMAGE, up_xpm);
813813 Chain members; /* its member frames */
814814 Name kind; /* {user,service} */
815815 Chain modal; /* Stack of modal frames */
816 Image icon_image; /* Image of the icon */
816817 End;
817818
818819
+0
-238
packages/xpce/src/install-sh less more
0 #!/bin/sh
1 #
2 # install - install a program, script, or datafile
3 # This comes from X11R5.
4 #
5 # Calling this script install-sh is preferred over install.sh, to prevent
6 # `make' implicit rules from creating a file called install from it
7 # when there is no Makefile.
8 #
9 # This script is compatible with the BSD install script, but was written
10 # from scratch.
11 #
12
13
14 # set DOITPROG to echo to test this script
15
16 # Don't use :- since 4.3BSD and earlier shells don't like it.
17 doit="${DOITPROG-}"
18
19
20 # put in absolute paths if you don't have them in your path; or use env. vars.
21
22 mvprog="${MVPROG-mv}"
23 cpprog="${CPPROG-cp}"
24 chmodprog="${CHMODPROG-chmod}"
25 chownprog="${CHOWNPROG-chown}"
26 chgrpprog="${CHGRPPROG-chgrp}"
27 stripprog="${STRIPPROG-strip}"
28 rmprog="${RMPROG-rm}"
29 mkdirprog="${MKDIRPROG-mkdir}"
30
31 tranformbasename=""
32 transform_arg=""
33 instcmd="$mvprog"
34 chmodcmd="$chmodprog 0755"
35 chowncmd=""
36 chgrpcmd=""
37 stripcmd=""
38 rmcmd="$rmprog -f"
39 mvcmd="$mvprog"
40 src=""
41 dst=""
42 dir_arg=""
43
44 while [ x"$1" != x ]; do
45 case $1 in
46 -c) instcmd="$cpprog"
47 shift
48 continue;;
49
50 -d) dir_arg=true
51 shift
52 continue;;
53
54 -m) chmodcmd="$chmodprog $2"
55 shift
56 shift
57 continue;;
58
59 -o) chowncmd="$chownprog $2"
60 shift
61 shift
62 continue;;
63
64 -g) chgrpcmd="$chgrpprog $2"
65 shift
66 shift
67 continue;;
68
69 -s) stripcmd="$stripprog"
70 shift
71 continue;;
72
73 -t=*) transformarg=`echo $1 | sed 's/-t=//'`
74 shift
75 continue;;
76
77 -b=*) transformbasename=`echo $1 | sed 's/-b=//'`
78 shift
79 continue;;
80
81 *) if [ x"$src" = x ]
82 then
83 src=$1
84 else
85 # this colon is to work around a 386BSD /bin/sh bug
86 :
87 dst=$1
88 fi
89 shift
90 continue;;
91 esac
92 done
93
94 if [ x"$src" = x ]
95 then
96 echo "install: no input file specified"
97 exit 1
98 else
99 true
100 fi
101
102 if [ x"$dir_arg" != x ]; then
103 dst=$src
104 src=""
105
106 if [ -d $dst ]; then
107 instcmd=:
108 else
109 instcmd=mkdir
110 fi
111 else
112
113 # Waiting for this to be detected by the "$instcmd $src $dsttmp" command
114 # might cause directories to be created, which would be especially bad
115 # if $src (and thus $dsttmp) contains '*'.
116
117 if [ -f $src -o -d $src ]
118 then
119 true
120 else
121 echo "install: $src does not exist"
122 exit 1
123 fi
124
125 if [ x"$dst" = x ]
126 then
127 echo "install: no destination specified"
128 exit 1
129 else
130 true
131 fi
132
133 # If destination is a directory, append the input filename; if your system
134 # does not like double slashes in filenames, you may need to add some logic
135
136 if [ -d $dst ]
137 then
138 dst="$dst"/`basename $src`
139 else
140 true
141 fi
142 fi
143
144 ## this sed command emulates the dirname command
145 dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
146
147 # Make sure that the destination directory exists.
148 # this part is taken from Noah Friedman's mkinstalldirs script
149
150 # Skip lots of stat calls in the usual case.
151 if [ ! -d "$dstdir" ]; then
152 defaultIFS='
153 '
154 IFS="${IFS-${defaultIFS}}"
155
156 oIFS="${IFS}"
157 # Some sh's can't handle IFS=/ for some reason.
158 IFS='%'
159 set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'`
160 IFS="${oIFS}"
161
162 pathcomp=''
163
164 while [ $# -ne 0 ] ; do
165 pathcomp="${pathcomp}${1}"
166 shift
167
168 if [ ! -d "${pathcomp}" ] ;
169 then
170 $mkdirprog "${pathcomp}"
171 else
172 true
173 fi
174
175 pathcomp="${pathcomp}/"
176 done
177 fi
178
179 if [ x"$dir_arg" != x ]
180 then
181 $doit $instcmd $dst &&
182
183 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi &&
184 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi &&
185 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi &&
186 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi
187 else
188
189 # If we're going to rename the final executable, determine the name now.
190
191 if [ x"$transformarg" = x ]
192 then
193 dstfile=`basename $dst`
194 else
195 dstfile=`basename $dst $transformbasename |
196 sed $transformarg`$transformbasename
197 fi
198
199 # don't allow the sed command to completely eliminate the filename
200
201 if [ x"$dstfile" = x ]
202 then
203 dstfile=`basename $dst`
204 else
205 true
206 fi
207
208 # Make a temp file name in the proper directory.
209
210 dsttmp=$dstdir/#inst.$$#
211
212 # Move or copy the file name to the temp name
213
214 $doit $instcmd $src $dsttmp &&
215
216 trap "rm -f ${dsttmp}" 0 &&
217
218 # and set any options; do chmod last to preserve setuid bits
219
220 # If any of these fail, we abort the whole thing. If we want to
221 # ignore errors from any of these, just make sure not to ignore
222 # errors from the above "$doit $instcmd $src $dsttmp" command.
223
224 if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi &&
225 if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi &&
226 if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi &&
227 if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi &&
228
229 # Now rename the file to the real destination.
230
231 $doit $rmcmd -f $dstdir/$dstfile &&
232 $doit $mvcmd $dsttmp $dstdir/$dstfile
233
234 fi &&
235
236
237 exit 0
+0
-9
packages/xpce/src/mkproto.sh less more
0 #!/bin/sh
1
2 # mkproto file ...
3 #
4 # Generate the proto.h files in the various subdirectories. mkproto is a
5 # public domain program to generate ANSI prototypes from C-sources.
6
7 mkproto -p -d COMMON -D '#define COMMON(type) SO_LOCAL type' $* | \
8 grep -vw NewClass | grep -v pceMT
+0
-12
packages/xpce/src/nomd less more
0 #!/bin/sh
1
2 arch=$1
3
4 echo "[ERROR: No machine description file for PLARCH=$arch]"
5
6 arches=`ls md | grep -v CVS | sed 's/md-\(.*\)\.h/\1/'`
7
8 echo ""
9 echo "Please edit PLARCH in Makefile to be one of:"
10 for a in $arches; do echo " $a"; done
11 exit 1
+0
-77
packages/xpce/src/rel-ln less more
0 #!/bin/sh
1 # Author: Stepan Kasal <kasal@suse.cz>
2 #
3 # Version: 0.1
4 # this shell script is public domain ;-)
5 # Modified: Thu Feb 17 2000 (JW)
6 # Avoid use of ln -sf (GNU specific)
7 # Avoid use of GNU sed extensions
8 # If all fails due to other links, make an absolute link.
9 # Modified: Thu Mar 9 2000 (JW)
10 # Avoid using grep -q (GNU specific)
11 #
12 # Purpose: Make relative links between the binary and lib directory to
13 # achieve a relocatable object. Notably useful for generating RPM files.
14
15 check_path()
16 { dir=$(dirname "$1")
17 file=$(basename "$1")
18 cdir=$(cd $dir && pwd)
19
20 echo $cdir/$file
21 }
22
23 compare()
24 { test $# = 4 && test "$1" = "$3" && from=$2 && to=$4
25 }
26
27 if test $# != 2 ; then
28 echo "usage: $0 from to
29 creates relative symbolic link from \$1 to \$2" >&2
30 exit 1
31 fi
32
33 from=$1
34 to=$2
35
36 from=$(check_path "$from")
37 to=$(check_path "$to")
38
39 # Make sure $to points to destination file instead of dir
40
41 if [ -d $to ]; then
42 to=$to/`basename $from`;
43 fi
44
45 abs_to="$to"
46 abs_from="$from"
47
48 # Remove leading / and replace repeated // into a single /
49
50 from=`echo $from | sed -e 's,//*,/,g' -e 's,/,,'`
51 to=`echo $to | sed -e 's,//*,/,g' -e 's,/,,'`
52
53 # Now get rid of the common start.
54
55 while compare `echo $from|sed "s,/, ,"` `echo $to|sed "s,/, ,"`
56 do test a = a
57 done
58
59 # Remove all but the last segment of $to into .. and put the from after this
60
61 relf="`echo $to | sed -e 's,[^/][^/]*/,../,g' -e 's,[^/][^/]*$,,'`$from"
62
63 rm -f "$abs_to"
64 # Cygwin specific test to find out if a symlink exists with a .exe suffix.
65 # Newer ln(1) create symlinks to executables also with a .exe suffix.
66 [ -s "$abs_to".exe ] && rm -f "$abs_to".exe
67
68 # Now, all can be in vain due to other symbolic links. If this is the case,
69 # link absolute after all.
70
71 if (cd `dirname $abs_to` && test -e $relf); then
72 ln -s "$relf" "$abs_to"
73 else
74 echo "`basename $0`: Making abolute link to $abs_from"
75 ln -s "$abs_from" "$abs_to"
76 fi
4242 assign(app, members, newObject(ClassChain, EAV));
4343 assign(app, kind, NAME_user);
4444 assign(app, modal, newObject(ClassChain, EAV));
45 obtainClassVariablesObject(app);
4546
4647 appendChain(TheApplications, app);
4748
203204 IV(NAME_kind, "{user,service}", IV_BOTH,
204205 NAME_debugging, "If service, events cannot be debugged"),
205206 IV(NAME_modal, "chain", IV_NONE,
206 NAME_event, "Frame for modal operation")
207 NAME_event, "Frame for modal operation"),
208 IV(NAME_iconImage, "image*", IV_BOTH,
209 NAME_icon, "Image used for the iconic representation")
207210 };
208211
209212 /* Send Methods */
238241
239242 /* Resources */
240243
241 #define rc_application NULL
242 /*
243244 static classvardecl rc_application[] =
244 {
245 };
246 */
245 { RC(NAME_iconImage, "image*", "@nil",
246 "Image displayed for an icon")
247 };
247248
248249 /* Class Declaration */
249250
267267 COMMON(int) write_gif_file(IOSTREAM *fd, XImage *img, XImage *msk,
268268 Display *disp, Colormap cmap);
269269 COMMON(XImage *) attachXpmImageImage(Image image, XpmImage *xpm);
270 COMMON(unsigned long *) XImageToRGBA(XImage *img, XImage *msk,
271 Display *disp, Colormap cmap, size_t *lenp);
270272
271273 /* xcolour.c */
272274 COMMON(status) allocNearestColour(Display *display, Colormap map,
274276
275277 extern XtAppContext ThePceXtAppContext; /* X toolkit application context */
276278
279 COMMON(unsigned long*) ws_image_to_rgba(Image image, Image mask, size_t *lenp);
280
277281 #endif /*_PCE_X11_INCLUDED*/
278282
7272
7373 XftPatternAddString(p, XFT_FAMILY, fam);
7474 XftPatternAddDouble(p, XFT_PIXEL_SIZE, (double)valInt(f->points)*fscale);
75 if ( f->style == NAME_italic )
75 if ( f->style == NAME_italic || f->style == NAME_oblique )
7676 XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ITALIC);
7777 else if ( f->style == NAME_roman )
7878 XftPatternAddInteger(p, XFT_SLANT, XFT_SLANT_ROMAN);
4646 static void destroyFrame(Widget, FrameObj, XtPointer);
4747 static status updateAreaFrame(FrameObj fr, Int border);
4848 static int ws_group_frame(FrameObj fr);
49 static int ws_set_pid_frame(FrameObj fr);
50 static void ws_set_net_icon_frame(FrameObj fr);
4951
5052 #define MainWindow(fr) ( isNil(fr->members->head) ? (Any) fr : \
5153 fr->members->head->value )
143145
144146 XtDestroyWidget(w);
145147 }
148 }
149
150
151 static Image
152 getIconFrame(FrameObj fr)
153 { if ( notNil(fr->application) && notNil(fr->application->icon_image) )
154 return fr->application->icon_image;
155
156 return fr->icon_image;
146157 }
147158
148159
153164 Widget w;
154165 DisplayObj d = fr->display;
155166 DisplayWsXref r = d->ws_ref;
167 Image icon;
156168
157169 XtSetArg(args[n], XtNtitle, nameToMB(fr->label)); n++;
158170 XtSetArg(args[n], XtNmappedWhenManaged, False); n++;
176188 { XtSetArg(args[n], XtNsaveUnder, True);
177189 n++;
178190 }
179 if ( notNil(fr->icon_image) )
191 if ( notNil(icon=getIconFrame(fr)) )
180192 { XtSetArg(args[n], XtNiconPixmap,
181 getXrefObject(fr->icon_image, fr->display));
193 getXrefObject(icon, fr->display));
182194 n++;
183 if ( notNil(fr->icon_image->mask) )
195 if ( notNil(icon->mask) )
184196 { XtSetArg(args[n], XtNiconMask,
185 getXrefObject(fr->icon_image->mask, fr->display));
197 getXrefObject(icon->mask, fr->display));
186198 n++;
187199 }
188200 }
262274
263275 ws_frame_background(fr, fr->background); /* Why is this necessary? */
264276 ws_group_frame(fr);
277 if ( notNil(fr->application) && notNil(fr->application->icon_image) )
278 ws_set_pid_frame(fr); /* group in Ubuntu dock */
279
280 ws_set_net_icon_frame(fr);
265281 }
266282
267283
409425
410426 fail;
411427 }
428
429 static int
430 ws_set_pid_frame(FrameObj fr)
431 { Widget w = widgetFrame(fr);
432 DisplayWsXref r = fr->display->ws_ref;
433 unsigned int xpid = getpid();
434 static Atom _net_wm_pid = 0;
435
436 if ( !_net_wm_pid )
437 _net_wm_pid = XInternAtom(r->display_xref,
438 "_NET_WM_PID",
439 False);
440
441 XChangeProperty(r->display_xref,
442 XtWindow(w),
443 _net_wm_pid,
444 XA_CARDINAL, 32, PropModeReplace,
445 (unsigned char *) &xpid, 1);
446
447 return TRUE;
448 }
449
412450
413451 #ifdef O_XDND
414452 /*******************************
13631401 }
13641402
13651403
1404 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1405 See https://stackoverflow.com/questions/10699927/xlib-argb-window-icon
1406 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1407
1408 static void
1409 ws_set_net_icon_frame(FrameObj fr)
1410 { unsigned long *buffer;
1411 size_t length;
1412 Image icon = getIconFrame(fr);
1413
1414 if ( notNil(icon) &&
1415 getXrefObject(icon, fr->display) &&
1416 (buffer=ws_image_to_rgba(icon, DEFAULT, &length)) )
1417 { Widget w = widgetFrame(fr);
1418 DisplayWsXref r = fr->display->ws_ref;
1419 static Atom _net_wm_icon = 0;
1420 static Atom cardinal = 0;
1421
1422 if ( !_net_wm_icon ) {
1423 _net_wm_icon = XInternAtom(r->display_xref,
1424 "_NET_WM_ICON",
1425 False);
1426 cardinal = XInternAtom(r->display_xref, "CARDINAL", False);
1427 }
1428
1429 XChangeProperty(r->display_xref,
1430 XtWindow(w),
1431 _net_wm_icon,
1432 cardinal, 32,
1433 PropModeReplace, (const unsigned char*) buffer, length);
1434
1435 free(buffer);
1436 }
1437 }
1438
1439
13661440 void
13671441 ws_set_icon_label_frame(FrameObj fr)
13681442 { Widget w = widgetFrame(fr);
149149 return errorPce(image, NAME_cannotSaveObject, NAME_noImage);
150150
151151 succeed;
152 }
153
154
155 unsigned long *
156 ws_image_to_rgba(Image image, Image mask, size_t *lenp)
157 { XImage *img, *msk = NULL;
158 int img_free=FALSE;
159 int msk_free=FALSE;
160 DisplayObj d = image->display;
161 DisplayWsXref r;
162 unsigned long *data;
163
164 if ( isNil(d) )
165 d = CurrentDisplay(image);
166 r = d->ws_ref;
167
168 if ( isDefault(mask) )
169 mask = image->mask;
170
171 if ( !(img=getXImageImage(image)) )
172 { if ( (img = getXImageImageFromScreen(image)) )
173 img_free = TRUE;
174 else
175 return NULL;
176 }
177
178 if ( notNil(mask) )
179 { if ( !(msk=getXImageImage(mask)) )
180 { if ( (msk = getXImageImageFromScreen(mask)) )
181 msk_free = TRUE;
182 }
183 }
184
185 data = XImageToRGBA(img, msk, r->display_xref, 0, lenp);
186 if ( img_free ) XDestroyImage(img);
187 if ( msk_free ) XDestroyImage(msk);
188
189 return data;
152190 }
153191
154192
9898 };
9999
100100 struct table
101 { int size;
101 { int size;
102102 Symbol symbols[1];
103103 };
104104
834834 c = pixelToColor(img, pixel, &info);
835835 r = intensityXColor(c);
836836 r = rescale(r, BRIGHT, scale);
837 if ( Sputc(r, fd) == EOF )
837 if ( Sputc(r, fd) == EOF )
838838 return -1;
839839 }
840840 }
882882
883883 return 0;
884884 }
885
886
887 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
888 Translate an XImage and an optional mask into an RBGA image in a format
889 that is suitable for _NET_WM_ICON.
890 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
891
892 unsigned long *
893 XImageToRGBA(XImage *img, XImage *msk,
894 Display *disp, Colormap cmap, size_t *lenp)
895 { int width = img->width;
896 int height = img->height;
897 XPixelInfo img_info;
898 XPixelInfo msk_info;
899 XColor img_cdata[256];
900 XColor msk_cdata[256];
901 int msk_is_bitmap = TRUE;
902 int x, y;
903 unsigned long *data, *p;
904 const int scale = 255;
905 size_t len;
906
907 if ( msk && (msk->height != height || msk->width != width) )
908 msk = NULL;
909
910 if ( img->format != XYBitmap )
911 { img_info.cinfo = img_cdata;
912 makeXPixelInfo(&img_info, img, disp, cmap);
913 }
914 if ( msk )
915 { if ( msk->format == XYBitmap ||
916 (msk->format == ZPixmap && msk->bits_per_pixel == 1) )
917 { msk_is_bitmap = TRUE;
918 } else
919 { msk_is_bitmap = FALSE;
920 msk_info.cinfo = msk_cdata;
921 makeXPixelInfo(&msk_info, msk, disp, cmap);
922 }
923 }
924
925 len = 2+width*height;
926 if ( lenp )
927 *lenp = len;
928 if ( !(data = malloc(len*sizeof(*data))) )
929 return data;
930 p = data;
931 *p++ = width;
932 *p++ = height;
933
934 for(y=0; y<height; y++)
935 { for(x=0; x<width; x++)
936 { XColor *c;
937 unsigned int r, g, b, a;
938 union
939 { unsigned int i32;
940 char c32[4];
941 } upix;
942
943 c = pixelToColor(img, XGetPixel(img, x, y), &img_info);
944 r = rescale(c->red, BRIGHT, scale);
945 g = rescale(c->green, BRIGHT, scale);
946 b = rescale(c->blue, BRIGHT, scale);
947
948 if ( msk )
949 { unsigned long pixel = XGetPixel(msk, x, y);
950 if ( msk_is_bitmap )
951 { a = pixel ? scale : 0;
952 } else
953 { XColor *c;
954 int r;
955
956 c = pixelToColor(img, pixel, &msk_info);
957 r = intensityXColor(c);
958 a = rescale(r, BRIGHT, scale);
959 }
960 } else
961 { a = 255;
962 }
963
964 upix.c32[0] = b; /* blue */
965 upix.c32[1] = g; /* green */
966 upix.c32[2] = r; /* red */
967 upix.c32[3] = a;
968 *p++ = upix.i32;
969 }
970 }
971
972 return data;
973 }
+0
-783
packages/xpce/src/xpce-copy.c less more
0 /* Part of XPCE --- The SWI-Prolog GUI toolkit
1
2 Author: Jan Wielemaker and Anjo Anjewierden
3 E-mail: J.Wielemaker@vu.nl
4 WWW: http://www.swi-prolog.org/projects/xpce/
5 Copyright (c) 2013, University of Amsterdam
6 VU University Amsterdam
7 All rights reserved.
8
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions
11 are met:
12
13 1. Redistributions of source code must retain the above copyright
14 notice, this list of conditions and the following disclaimer.
15
16 2. Redistributions in binary form must reproduce the above copyright
17 notice, this list of conditions and the following disclaimer in
18 the documentation and/or other materials provided with the
19 distribution.
20
21 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
36 SYNOPSIS:
37 xpce-copy [-v] [-c] [-m mode] from to
38 xpce-copy [-v] [-c] [-m mode] [-p] file file ... dir
39
40 Simple install replacement to be used for XPCE installation. The
41 configure install.sh script is very slow, while all operating systems
42 appear to be using different versions of install. This should solve this
43 problem.
44
45 This installer is also used to install the system under windows to avoid
46 the limitiations and portability issues around the Windows command
47 interpreter and copy command.
48 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
49
50 #ifdef HAVE_CONFIG_H
51 #include <config.h>
52 #endif
53
54 #include <stdio.h>
55 #include <stdlib.h>
56 #include <ctype.h>
57 #include <sys/types.h>
58 #include <sys/stat.h>
59 #ifdef HAVE_UNISTD_H
60 #include <unistd.h>
61 #endif
62 #include <fcntl.h>
63 #include <errno.h>
64 #include <time.h>
65 #include <string.h>
66
67 #ifndef MAXPATHLEN
68 #define MAXPATHLEN 1024
69 #endif
70
71 #ifndef TRUE
72 #define TRUE 1
73 #define FALSE 0
74 #endif
75
76 #define bool int
77 #define shift (argc--, argv++)
78
79 #define CPBUFSIZE 8192
80
81 #ifndef O_BINARY
82 #define O_BINARY 0
83 #endif
84
85 #if defined(_MSC_VER) || defined(__MINGW32__)
86 #ifndef __WINDOWS__
87 #define __WINDOWS__
88 #endif
89 #endif
90
91 #ifdef __WINDOWS__
92 #include <io.h> /* read, write, etc */
93 #include <direct.h> /* mkdir, chdir */
94 #define IsDirSep(c) ((c) == '/' || (c) == '\\')
95 #define DIRSEP '\\'
96 #define mode_t unsigned short
97 #else
98 #define IsDirSep(c) ((c) == '/')
99 #define DIRSEP '/'
100 #endif
101
102 /*******************************
103 * SETTINGS *
104 *******************************/
105
106 unsigned short mode;
107 bool set_mode;
108 bool copy;
109 char * program;
110 int verbose=0;
111 bool makedirs;
112 bool strippath = -1; /* i.e. use basename() */
113 bool installdirs = FALSE; /* -d */
114 bool newer_only = FALSE;
115
116 static int
117 get_mode(const char *s, unsigned short *m)
118 { unsigned short mode = 0;
119
120 while(*s >= '0' && *s <= '7')
121 { mode = (mode << 3) + *s++ - '0';
122 }
123
124 if ( *s )
125 return FALSE;
126
127 *m = mode;
128 return TRUE;
129 }
130
131
132 static int
133 isdir(const char *path)
134 { struct stat buf;
135 char tmp[MAXPATHLEN];
136 char *s;
137
138 strcpy(tmp, path); /* delete trailing / to work */
139 s = tmp+strlen(tmp); /* around bugs in some runtime */
140 if ( s>tmp && s[-1] == '/' ) /* libraries */
141 *--s = 0;
142
143 if ( stat(tmp, &buf) < 0 ||
144 (buf.st_mode & S_IFMT) != S_IFDIR )
145 return FALSE;
146
147 return TRUE;
148 }
149
150
151 static void
152 get_file_mode(const char *name, int fd, mode_t *m)
153 { struct stat buf;
154
155 #ifdef HAVE_FSTAT
156 if ( fstat(fd, &buf) == 0 )
157 #else
158 if ( stat(name, &buf) == 0 )
159 #endif
160 *m = buf.st_mode;
161 else
162 *m = 0755; /* default (hack) */
163 }
164
165
166 static int
167 last_modified(const char *name, time_t *t)
168 { struct stat buf;
169
170 if ( stat(name, &buf) == 0 )
171 { *t = buf.st_mtime;
172 return 0;
173 } else
174 return -1;
175 }
176
177
178 const char *
179 basename(const char *path)
180 { const char *base;
181
182 for(base=path; *path; path++)
183 { if ( IsDirSep(*path) )
184 base = path+1;
185 }
186
187 return base;
188 }
189
190
191 char *
192 dirname(const char *path) /* returns malloced directory name */
193 { const char *base = basename(path);
194 char *rval;
195
196 while(base > path && IsDirSep(base[-1]) )
197 base--;
198
199 if ( !(rval = malloc(base-path+1)) )
200 { perror("malloc");
201 exit(1);
202 }
203 memcpy(rval, path, base-path);
204 rval[base-path] = '\0';
205
206 return rval;
207 }
208
209
210 static int
211 makedir(char *path)
212 { again:
213
214 #ifdef __WINDOWS__
215 if ( mkdir(path) == 0 )
216 #else
217 if ( mkdir(path, 0777) == 0 )
218 #endif
219 { free(path);
220 return TRUE;
221 }
222
223 if ( errno == ENOENT )
224 { if ( makedir(dirname(path)) )
225 goto again;
226 }
227
228 free(path);
229 return FALSE;
230 }
231
232
233 static char *
234 str_store(const char *in)
235 { char *rval;
236
237 if ( (rval = malloc(strlen(in)+1)) )
238 { strcpy(rval, in);
239 return rval;
240 }
241
242 perror("malloc");
243 exit(1);
244 }
245
246
247 static int
248 install_dir(const char *name)
249 { if ( !isdir(name) )
250 return makedir(str_store(name));
251
252 return TRUE;
253 }
254
255
256 static int
257 install_file(const char *from, const char *to)
258 { int fdfrom, fdto;
259 char buf[CPBUFSIZE];
260 int rval;
261 int n;
262 mode_t m;
263
264 if ( newer_only )
265 { time_t to_time;
266
267 if ( last_modified(to, &to_time) == 0 )
268 { time_t from_time;
269
270 if ( last_modified(from, &from_time) != 0 )
271 { perror(from);
272 return FALSE;
273 }
274
275 if ( difftime(from_time, to_time) < 0.0 )
276 { if ( verbose >= 2 )
277 fprintf(stderr, "Skipped %s (not modified)\n", to);
278 return TRUE;
279 }
280 }
281 }
282
283 if ( (fdfrom = open(from, O_RDONLY|O_BINARY)) < 0 )
284 { perror(from);
285 return FALSE;
286 }
287
288 if ( set_mode )
289 m = mode;
290 else
291 get_file_mode(from, fdfrom, &m);
292
293 unlink(to);
294 again:
295 if ( (fdto = open(to, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC, m)) < 0 )
296 { if ( errno == ENOENT && makedir(dirname(to)) )
297 goto again;
298 perror(to);
299 close(fdfrom);
300 return FALSE;
301 }
302
303 while( (n = read(fdfrom, buf, CPBUFSIZE)) > 0 )
304 { char *b = buf;
305
306 while(n > 0)
307 { int n2;
308
309 if ( (n2=write(fdto, b, n)) < 0 )
310 { perror(to);
311 rval = FALSE;
312 goto out;
313 }
314 b += n2;
315 n -= n2;
316 }
317 }
318 if ( n < 0 )
319 { perror(from);
320 rval = FALSE;
321 } else
322 rval = TRUE;
323
324 out:
325 close(fdfrom);
326 close(fdto);
327
328 return rval;
329 }
330
331
332 const char *
333 strip_path(const char *path, int strip)
334 { if ( strip < 0 )
335 return basename(path);
336 else
337 { const char *base = path;
338
339 while(strip-- > 0)
340 { while( IsDirSep(*base) )
341 base++;
342 while( *base && !IsDirSep(*base) )
343 base++;
344 while( IsDirSep(*base) )
345 base++;
346 }
347
348 return base;
349 }
350 }
351
352
353 static int
354 install_file_in_dir(const char *file, const char *dir)
355 { char path[MAXPATHLEN];
356 const char *base = strip_path(file, strippath);
357 int rval;
358
359 sprintf(path, "%s%c%s", dir, DIRSEP, base);
360
361 if ( (rval = install_file(file, path)) && verbose )
362 printf("%s\n", base);
363
364 return rval;
365 }
366
367 /*******************************
368 * IGNORE *
369 *******************************/
370
371 #define MAXLINE 1024
372 #define EOS '\0'
373
374 int compilePattern(const char *p);
375 int matchPattern(const char *s);
376
377 typedef struct icell *Icell;
378
379 struct icell
380 { char *pattern;
381 Icell next;
382 };
383
384 typedef struct
385 { Icell head;
386 Icell tail;
387 } ilist, *Ilist;
388
389 ilist _ignore_patterns;
390 Ilist ignore_patterns = &_ignore_patterns;
391
392 void
393 to_ignore_list(Ilist ign, const char *pattern)
394 { char *p = str_store(pattern);
395 Icell c = malloc(sizeof(struct icell));
396
397 c->pattern = p;
398 c->next = NULL;
399 if ( ign->tail )
400 { ign->tail->next = c;
401 ign->tail = c;
402 } else
403 { ign->head = ign->tail = c;
404 }
405 }
406
407
408 int
409 ignore(Ilist ign, const char *name)
410 { Icell c;
411
412 for(c = ignore_patterns->head; c; c=c->next)
413 { compilePattern(c->pattern);
414 if ( matchPattern(name) )
415 return TRUE;
416 }
417 for(c = ign->head; c; c=c->next)
418 { compilePattern(c->pattern);
419 if ( matchPattern(name) )
420 return TRUE;
421 }
422
423 return FALSE;
424 }
425
426
427 static void
428 ignoreForDir(Ilist l, char *d)
429 { char n[MAXPATHLEN];
430 FILE *fd;
431
432 sprintf(n, "%s%c.cvsignore", d, DIRSEP);
433 if ( (fd = fopen(n, "r")) )
434 { char p[MAXLINE];
435
436 while( fgets(p, sizeof(p), fd) )
437 { char *s = p;
438 int len;
439
440 while(*s && *s < ' ')
441 s++;
442 len = strlen(s);
443
444 while( len > 0 && s[len-1] < ' ' )
445 len--;
446 s[len] = EOS;
447
448 if ( len > 0 )
449 { if ( verbose )
450 printf("ignore %s in %s\n", s, d);
451 to_ignore_list(l, s);
452 }
453 }
454
455 fclose(fd);
456 }
457 }
458
459
460 /*******************************
461 * WILDCHART MATCH *
462 *******************************/
463
464 #define succeed return(TRUE);
465 #define fail return(FALSE);
466 #ifndef uchar
467 #define uchar unsigned char
468 #endif
469
470 #define MAXCODE 512
471
472 #define ANY 128
473 #define STAR 129
474 #define ALT 130
475 #define JMP 131
476 #define ANYOF 132
477 #define EXIT 133
478
479 #define NOCURL 0
480 #define CURL 1
481
482 #define warning(text) \
483 (fprintf(stderr, "%s: bad pattern: %s\n", program, text), \
484 exit(0))
485
486 #define Output(c) { if ( Out->size > MAXCODE-1 ) \
487 { warning("pattern too large"); \
488 return (char *) NULL; \
489 } \
490 Out->code[Out->size++] = c; \
491 }
492 #define setMap(c) { map[(c)/8] |= 1 << ((c) % 8); }
493
494 static struct _pattern_buffer
495 { int size;
496 uchar code[MAXCODE];
497 } default_pattern_buffer;
498
499 static char *compile_pattern(struct _pattern_buffer*, const char *, int);
500 static int match_pattern(uchar *, const char *);
501
502 int
503 compilePattern(const char *p)
504 { default_pattern_buffer.size = 0;
505 if ( compile_pattern(&default_pattern_buffer, p, NOCURL) == (char *) NULL )
506 fail;
507
508 succeed;
509 }
510
511
512 static char *
513 compile_pattern(struct _pattern_buffer *Out, const char *p, int curl)
514 { char c;
515
516 for(;;)
517 { switch(c = *p++)
518 { case EOS:
519 break;
520 case '\\':
521 Output(*p == EOS ? '\\' : (*p & 0x7f));
522 if (*p == EOS )
523 break;
524 p++;
525 continue;
526 case '?':
527 Output(ANY);
528 continue;
529 case '*':
530 Output(STAR);
531 continue;
532 case '[':
533 { uchar *map;
534 int n;
535
536 Output(ANYOF);
537 map = &Out->code[Out->size];
538 Out->size += 16;
539 if ( Out->size >= MAXCODE )
540 { warning("Pattern too long");
541 return (char *) NULL;
542 }
543
544 for( n=0; n < 16; n++)
545 map[n] = 0;
546
547 for(;;)
548 { switch( c = *p++ )
549 { case '\\':
550 if ( *p == EOS )
551 { warning("Unmatched '['");
552 return (char *)NULL;
553 }
554 setMap(*p);
555 p++;
556 continue;
557 case ']':
558 break;
559 default:
560 if ( p[-1] != ']' && p[0] == '-' && p[1] != ']' )
561 { register int chr;
562
563 for ( chr=p[-1]; chr <= p[1]; chr++ )
564 setMap(chr);
565 p += 2;
566 } else
567 setMap(c);
568 continue;
569 }
570 break;
571 }
572
573 continue;
574 }
575 case '{':
576 { int ai, aj = -1;
577
578 for(;;)
579 { Output(ALT); ai = Out->size; Output(0);
580 if ( (p = compile_pattern(Out, p, CURL)) == (char *) NULL )
581 return (char *) NULL;
582 if ( aj > 0 )
583 Out->code[aj] = Out->size - aj;
584 if ( *p == ',' )
585 { Output(JMP); aj = Out->size; Output(0);
586 Out->code[ai] = Out->size - ai;
587 Output(ALT); ai = Out->size; Output(0);
588 p++;
589 } else if ( *p == '}' )
590 { p++;
591 break;
592 } else
593 { warning("Unmatched '{'");
594 return (char *) NULL;
595 }
596 }
597
598 continue;
599 }
600 case '}':
601 case ',':
602 if ( curl == CURL )
603 { p--;
604 return (char *)p;
605 }
606 /*FALLTHROUGH*/
607 default:
608 Output(c & 0x7f);
609 continue;
610 }
611
612 Output(EXIT);
613 return (char *)p;
614 }
615 }
616
617
618 int
619 matchPattern(const char *s)
620 { return match_pattern(default_pattern_buffer.code, s);
621 }
622
623
624 static int
625 match_pattern(uchar *p, const char *s)
626 { uchar c;
627
628 for(;;)
629 { switch( c = *p++ )
630 { case EXIT:
631 return (*s == EOS ? TRUE : FALSE);
632 case ANY: /* ? */
633 if ( *s == EOS )
634 fail;
635 s++;
636 continue;
637 case ANYOF: /* [...] */
638 if ( p[*s / 8] & (1 << (*s % 8)) )
639 { p += 16;
640 s++;
641 continue;
642 }
643 fail;
644 case STAR: /* * */
645 do
646 { if ( match_pattern(p, s) )
647 succeed;
648 } while( *s++ );
649 fail;
650 case JMP: /* { ... } */
651 p += *p;
652 continue;
653 case ALT:
654 if ( match_pattern(p+1, s) )
655 succeed;
656 p += *p;
657 continue;
658 default: /* character */
659 if ( c != (uchar) *s )
660 fail;
661 s++;
662 continue;
663 }
664 }
665 }
666
667 /*******************************
668 * MAIN *
669 *******************************/
670
671 void
672 usage()
673 { fprintf(stderr, " Usage: %s options file ... directory\n", program);
674 fprintf(stderr, " or: %s options from to\n", program);
675 fprintf(stderr, " or: %s [-C dir] -d dir ...\n", program);
676 fprintf(stderr, "options: [-v[N]] [-n] [-c] [-p[N]] [-C dir] [-m mode]\n");
677 exit(1);
678 }
679
680
681 int
682 main(int argc, char **argv)
683 { char *out;
684 int errors = 0;
685
686 program = argv[0];
687 shift;
688 while(argc > 0 && argv[0][0] == '-')
689 { char *opts = &argv[0][1];
690
691 shift;
692 for( ; *opts; opts++ )
693 { switch( *opts )
694 { case 'c':
695 copy = TRUE;
696 break;
697 case 'p':
698 strippath = 0;
699 makedirs = TRUE;
700 if ( isdigit(opts[1]&0xff) )
701 { opts++;
702 strippath = *opts - '0';
703 }
704 break;
705 case 'd':
706 installdirs = TRUE;
707 break;
708 case 'n':
709 newer_only = TRUE;
710 break;
711 case 'v':
712 verbose++;
713 if ( isdigit(opts[1]&0xff) )
714 { opts++;
715 verbose = *opts - '0';
716 }
717 break;
718 case 'C':
719 { char *dir = argv[0];
720
721 shift;
722 if ( chdir(dir) != 0 )
723 { perror(dir);
724 exit(1);
725 }
726 break;
727 }
728 case 'm':
729 if ( argc > 0 && get_mode(argv[0], &mode) )
730 { shift;
731 set_mode = TRUE;
732 }
733 break;
734 default:
735 usage();
736 }
737 }
738 }
739
740 if ( argc == 0 )
741 usage();
742 out = argv[argc-1];
743
744 if ( installdirs )
745 { int i;
746
747 for(i=0; i<argc; i++)
748 { if ( !install_dir(argv[i]) )
749 errors++;
750 }
751 } else
752 { if ( isdir(out) )
753 { int i;
754
755 to_ignore_list(ignore_patterns, "*~");
756 to_ignore_list(ignore_patterns, "*.bak");
757 to_ignore_list(ignore_patterns, "*.old");
758 to_ignore_list(ignore_patterns, ".cvsignore");
759 to_ignore_list(ignore_patterns, "CVS");
760 ignoreForDir(ignore_patterns, out);
761
762 for(i=0; i<argc-1; i++)
763 { if ( ignore(ignore_patterns, argv[i]) )
764 continue;
765
766 if ( isdir(argv[i]) )
767 { if ( verbose )
768 fprintf(stderr, "Skipping directory %s\n", argv[i]);
769 continue;
770 }
771
772 if ( !install_file_in_dir(argv[i], out) )
773 errors++;
774 }
775 } else
776 { if ( !install_file(argv[0], out) )
777 errors++;
778 }
779 }
780
781 return errors ? 1 : 0;
782 }
9393 build_PPAs()
9494 { git branch -D ppa || true
9595 git checkout -b ppa
96 for distro in xenial bionic disco eoan; do
96 for distro in xenial bionic disco eoan focal; do
9797 ./scripts/make-ppa --distro=$distro --push
9898 done
9999 git checkout master
101101 }
102102
103103 build()
104 { build_pdf
105 build_win32
106 build_win64
107 build_source
108 build_PPAs
104 { if [ $(uname) = Darwin ]; then
105 build_macosx_gcc
106 else
107 build_pdf
108 build_win32
109 build_win64
110 build_source
111 build_PPAs
112 fi
109113 }
110114
111115 ################
126130 }
127131
128132 upload_macosx()
129 { upload_file bin build.macosx/swipl-${version}-1.x86_64.dmg
133 { if [ -f build.macosx-gcc/swipl-${version}-1.x86_64.dmg ]; then
134 echo "Uploading fast GCC version"
135 upload_file bin build.macosx-gcc/swipl-${version}-1.x86_64.dmg
136 else
137 echo "WARNING: uploading slow Clang version"
138 upload_file bin build.macosx/swipl-${version}-1.x86_64.dmg
139 fi
130140 }
131141
132142 upload_pdf()
77 PL_VERSION=`cat VERSION`
88 VTAG=HEAD
99 TARGET_DISTRO=none
10 distros="xenial bionic disco eoan"
10 distros="xenial bionic disco eoan focal"
1111 build=true
1212 buildbin=false
1313 push=false
11
22 ## Building
33
4 snapcraft clean swi-prolog
45 snapcraft
56
67 ## Local testing
8888 - libxt6
8989 - odbc-postgresql
9090 - tdsodbc
91 - libtcmalloc-minimal4
9192 - unixodbc
9293 build-packages:
9394 - libarchive-dev
114115 - zlib1g-dev
115116 - libyaml-dev
116117 - libglvnd-dev
118 - libgoogle-perftools-dev
77 # This file is processed using defatom, compiled from defatom.c to
88 # produce pl-atom.ic, pl-atom.ih, pl-funct.ic and pl-funct.ih.
99
10 A abi "abi"
1011 A abort "abort"
1112 A aborted "$aborted"
1213 A abs "abs"
9192 A btree "btree"
9293 A buffer "buffer"
9394 A buffer_size "buffer_size"
95 A built_in "built_in"
9496 A built_in_procedure "built_in_procedure"
9597 A busy "busy"
9698 A byte "byte"
321323 A floor "floor"
322324 A force "force"
323325 A foreign "foreign"
326 A foreign_interface "foreign_interface"
324327 A foreign_function "$foreign_function"
325328 A foreign_return_value "foreign_return_value"
326329 A fork "fork"
619622 A prove ":-"
620623 A public "public"
621624 A punct "punct"
625 A qlf "qlf"
626 A qlf_min_load "qlf_min_load"
622627 A quasi_quotation "quasi_quotation"
623628 A quasi_quotation_position "quasi_quotation_position"
624629 A quasi_quotation_syntax "quasi_quotation_syntax"
136136 sandbox.pl prolog_format.pl prolog_install.pl check_installation.pl
137137 solution_sequences.pl iostream.pl dicts.pl yall.pl tabling.pl
138138 lazy_lists.pl prolog_jiti.pl zip.pl obfuscate.pl wfs.pl
139 prolog_wrap.pl prolog_trace.pl prolog_code.pl intercept.pl)
139 prolog_wrap.pl prolog_trace.pl prolog_code.pl intercept.pl
140 prolog_deps.pl)
140141 if(INSTALL_DOCUMENTATION)
141142 set(SWIPL_DATA_library ${SWIPL_DATA_library} help.pl)
142143 endif()
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2008-2017, University of Amsterdam
5 Copyright (c) 2008-2020, University of Amsterdam
66 VU University Amsterdam
77 All rights reserved.
88
6767 /* PLVERSION_TAG: a string, normally "", but for example "rc1" */
6868
6969 #ifndef PLVERSION
70 #define PLVERSION 80129
70 #define PLVERSION 80130
7171 #endif
7272 #ifndef PLVERSION_TAG
7373 #define PLVERSION_TAG ""
7474 #endif
75
76 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
77 This number is incremented when the SWI-Prolog PL_*() functions or one
78 of the data types is modified such that old binary extensions cannot run
79 reliably with the current version. This version is introduced in
80 SWI-Prolog 8.1.30. The most recent violation of compatibility was
81 between versions 8.1.21 and 8.1.22 with the introduction of rational
82 numbers are atomic type.
83 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
84
85 #define PL_FLI_VERSION 2 /* PL_*() functions */
86 #define PL_REC_VERSION 3 /* PL_record_external(), fastrw */
87 #define PL_QLF_LOADVERSION 67 /* load all versions later >= X */
88 #define PL_QLF_VERSION 67 /* save version number */
7589
7690
7791 /*******************************
190204 size_t arity;
191205 } t;
192206 } term_value_t;
207
193208
194209 #ifndef TRUE
195210 #define TRUE (1)
484499 PL_EXPORT(int) PL_get_module(term_t t, module_t *module) WUNUSED;
485500 PL_EXPORT(int) PL_get_arg_sz(size_t index, term_t t, term_t a) WUNUSED;
486501 PL_EXPORT(int) PL_get_arg(int index, term_t t, term_t a) WUNUSED;
502 PL_EXPORT(int) PL_get_dict_key(atom_t key, term_t dict, term_t value);
487503 PL_EXPORT(int) PL_get_list(term_t l, term_t h, term_t t) WUNUSED;
488504 PL_EXPORT(int) PL_get_head(term_t l, term_t h) WUNUSED;
489505 PL_EXPORT(int) PL_get_tail(term_t l, term_t t) WUNUSED;
504520 PL_EXPORT(int) PL_is_callable(term_t t);
505521 PL_EXPORT(int) PL_is_functor(term_t t, functor_t f);
506522 PL_EXPORT(int) PL_is_list(term_t t);
523 PL_EXPORT(int) PL_is_dict(term_t t);
507524 PL_EXPORT(int) PL_is_pair(term_t t);
508525 PL_EXPORT(int) PL_is_atomic(term_t t);
509526 PL_EXPORT(int) PL_is_number(term_t t);
530547 PL_EXPORT(int) PL_put_list(term_t l) WUNUSED;
531548 PL_EXPORT(int) PL_put_nil(term_t l);
532549 PL_EXPORT(int) PL_put_term(term_t t1, term_t t2);
550 PL_EXPORT(int) PL_put_dict(term_t t, atom_t tag, size_t len,
551 const atom_t *keys, term_t values);
533552
534553 /* construct a functor or list-cell */
535554 PL_EXPORT(int) PL_cons_functor(term_t h, functor_t f, ...) WUNUSED;
837856 #define CVT_EXCEPTION 0x00001000 /* throw exception on error */
838857 #define CVT_VARNOFAIL 0x00002000 /* return 2 if argument is unbound */
839858
840 #define BUF_DISCARDABLE 0x00000000
841 #define BUF_RING 0x00010000
842 #define BUF_MALLOC 0x00020000
843 #define BUF_ALLOW_STACK 0x00040000 /* allow pointer into (global) stack */
859 #define BUF_DISCARDABLE 0x00000000 /* Store in single thread-local buffer */
860 #define BUF_RING 0x00010000 /* Store in ring of 16 buffers */
861 #define BUF_MALLOC 0x00020000 /* Store using PL_malloc() */
862 #define BUF_ALLOW_STACK 0x00040000 /* Allow pointer into (global) stack */
863 #define BUF_NORING 0x00080000 /* Do not store in ring */
844864
845865
846866 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
10851105 PL_EXPORT(int) PL_current_prolog_flag(atom_t name, int type, void *ptr);
10861106
10871107
1108 /*******************************
1109 * VERSIONS *
1110 *******************************/
1111
1112 #define PL_VERSION_SYSTEM 1 /* Prolog version */
1113 #define PL_VERSION_FLI 2 /* PL_* compatibility */
1114 #define PL_VERSION_REC 3 /* PL_record_external() compatibility */
1115 #define PL_VERSION_QLF 4 /* Saved QLF format version */
1116 #define PL_VERSION_QLF_LOAD 5 /* Min loadable QLF format version */
1117 #define PL_VERSION_VM 6 /* VM signature */
1118 #define PL_VERSION_BUILT_IN 7 /* Built-in predicate signature */
1119
1120 PL_EXPORT(unsigned int) PL_version(int which);
1121
1122
10881123 /********************************
10891124 * QUERY PROLOG *
10901125 *********************************/
0 % Author: Bart Demoen K.U.Leuven
1 % Date: Oct 21 1996
2
3 makeground([]) .
4 makeground([X|R]) :- mkgr(X) , makeground(R) .
5
6 mkgr(X) :- var(X) , ! , (X = g ; X = i ; X = v) .
7 mkgr(_) .
8
9 mymember(X,[Y|R]) :- mm(X,R,Y) .
10 mm(X,_,X) .
11 mm(X,[Y|R],_) :- mm(X,R,Y) .
12
13 :- table(compute1/4) .
14
15 compute(Vars,DRs,Mal,DR) :- compute1(Vars,DRs,Mal,DR), fail .
16 compute(Vars,DRs,Mal,DR) :- compute1(Vars,DRs,Mal,DR).
17
18 compute1(Vars,DRs,Mal,DR) :-
19 findall(Mal,(lookup(Vars,DRs),makeground(Mal)),All),
20 sort(All,DR) .
21
22 lookup([],[]) .
23 lookup([V|VarList],[DR|DRList]) :- mymember(V,DR) , lookup(VarList,DRList) .
24
25 fail_iff_0([],_) :- fail .
26
27 iffequal_2([_,_],[[g,g],[i,i],[v,v]]) .
28
29 iff_1([_],[[g]]) .
30
31 iff_2([_,_],
32 [[g,g],
33 [i,i],
34 [i,v]]) .
35
36 iff_3([_,_,_],
37 [[g,g,g],
38 [i,g,i],
39 [i,g,v],
40 [i,i,g],
41 [i,i,i],
42 [i,i,v],
43 [i,v,g],
44 [i,v,i],
45 [i,v,v]]) .
46
47 iff_4([_,_,_,_],
48 [[g,g,g,g],
49 [i,g,g,i],
50 [i,g,g,v],
51 [i,g,i,g],
52 [i,g,i,i],
53 [i,g,i,v],
54 [i,g,v,g]|R]) :- r4_1(R) .
55 r4_1([
56 [i,g,v,i],
57 [i,g,v,v],
58 [i,i,g,g],
59 [i,i,g,i],
60 [i,i,g,v],
61 [i,i,i,g],
62 [i,i,i,i],
63 [i,i,i,v],
64 [i,i,v,g],
65 [i,i,v,i],
66 [i,i,v,v]|R]) :- r4_2(R) .
67 r4_2([
68 [i,v,g,g],
69 [i,v,g,i],
70 [i,v,g,v],
71 [i,v,i,g],
72 [i,v,i,i],
73 [i,v,i,v],
74 [i,v,v,g],
75 [i,v,v,i],
76 [i,v,v,v]]) .
77
78
79 iff_5([_,_,_,_,_],
80 [[g,g,g,g,g],
81 [i,g,g,g,i],
82 [i,g,g,g,v],
83 [i,g,g,i,g],
84 [i,g,g,i,i],
85 [i,g,g,i,v],
86 [i,g,g,v,g],
87 [i,g,g,v,i],
88 [i,g,g,v,v],
89 [i,g,i,g,g]|R]) :- r5_1(R) .
90 r5_1([
91 [i,g,i,g,i],
92 [i,g,i,g,v],
93 [i,g,i,i,g],
94 [i,g,i,i,i],
95 [i,g,i,i,v],
96 [i,g,i,v,g],
97 [i,g,i,v,i],
98 [i,g,i,v,v],
99 [i,g,v,g,g],
100 [i,g,v,g,i]|R]) :- r5_2(R) .
101 r5_2([
102 [i,g,v,g,v],
103 [i,g,v,i,g],
104 [i,g,v,i,i],
105 [i,g,v,i,v],
106 [i,g,v,v,g],
107 [i,g,v,v,i],
108 [i,g,v,v,v],
109 [i,i,g,g,g],
110 [i,i,g,g,i]|R]) :- r5_3(R) .
111 r5_3([
112 [i,i,g,g,v],
113 [i,i,g,i,g],
114 [i,i,g,i,i],
115 [i,i,g,i,v],
116 [i,i,g,v,g],
117 [i,i,g,v,i],
118 [i,i,g,v,v],
119 [i,i,i,g,g],
120 [i,i,i,g,i]|R]) :- r5_4(R) .
121 r5_4([
122 [i,i,i,g,v],
123 [i,i,i,i,g],
124 [i,i,i,i,i],
125 [i,i,i,i,v],
126 [i,i,i,v,g],
127 [i,i,i,v,i],
128 [i,i,i,v,v],
129 [i,i,v,g,g],
130 [i,i,v,g,i]|R]) :- r5_5(R) .
131 r5_5([
132 [i,i,v,g,v],
133 [i,i,v,i,g],
134 [i,i,v,i,i],
135 [i,i,v,i,v],
136 [i,i,v,v,g],
137 [i,i,v,v,i],
138 [i,i,v,v,v],
139 [i,v,g,g,g],
140 [i,v,g,g,i]|R]) :- r5_6(R) .
141 r5_6([
142 [i,v,g,g,v],
143 [i,v,g,i,g],
144 [i,v,g,i,i],
145 [i,v,g,i,v],
146 [i,v,g,v,g],
147 [i,v,g,v,i],
148 [i,v,g,v,v],
149 [i,v,i,g,g],
150 [i,v,i,g,i]|R]) :- r5_7(R) .
151 r5_7([
152 [i,v,i,g,v],
153 [i,v,i,i,g],
154 [i,v,i,i,i],
155 [i,v,i,i,v],
156 [i,v,i,v,g],
157 [i,v,i,v,i],
158 [i,v,i,v,v],
159 [i,v,v,g,g]|R]) :- r5_8(R) .
160 r5_8([
161 [i,v,v,g,i],
162 [i,v,v,g,v],
163 [i,v,v,i,g],
164 [i,v,v,i,i],
165 [i,v,v,i,v],
166 [i,v,v,v,g],
167 [i,v,v,v,i],
168 [i,v,v,v,v]]) .
169
170 iff_6([_,_,_,_,_,_],
171 [[g,g,g,g,g,g],
172 [i,g,g,g,g,i],
173 [i,g,g,g,g,v],
174 [i,g,g,g,i,g],
175 [i,g,g,g,i,i]|R]) :- r6_1(R) .
176 r6_1([
177 [i,g,g,g,i,v],
178 [i,g,g,g,v,g],
179 [i,g,g,g,v,i],
180 [i,g,g,g,v,v],
181 [i,g,g,i,g,g],
182 [i,g,g,i,g,i]|R]) :- r6_2(R) .
183 r6_2([
184 [i,g,g,i,g,v],
185 [i,g,g,i,i,g],
186 [i,g,g,i,i,i],
187 [i,g,g,i,i,v],
188 [i,g,g,i,v,g],
189 [i,g,g,i,v,i],
190 [i,g,g,i,v,v]|R]) :- r6_3(R) .
191 r6_3([
192 [i,g,g,v,g,g],
193 [i,g,g,v,g,i],
194 [i,g,g,v,g,v],
195 [i,g,g,v,i,g],
196 [i,g,g,v,i,i],
197 [i,g,g,v,i,v],
198 [i,g,g,v,v,g],
199 [i,g,g,v,v,i]|R]) :- r6_4(R) .
200 r6_4([
201 [i,g,g,v,v,v],
202 [i,g,i,g,g,g],
203 [i,g,i,g,g,i],
204 [i,g,i,g,g,v],
205 [i,g,i,g,i,g],
206 [i,g,i,g,i,i],
207 [i,g,i,g,i,v],
208 [i,g,i,g,v,g]|R]) :- r6_5(R) .
209 r6_5([
210 [i,g,i,g,v,i],
211 [i,g,i,g,v,v],
212 [i,g,i,i,g,g],
213 [i,g,i,i,g,i],
214 [i,g,i,i,g,v],
215 [i,g,i,i,i,g],
216 [i,g,i,i,i,i],
217 [i,g,i,i,i,v],
218 [i,g,i,i,v,g]|R]) :- r6_6(R) .
219 r6_6([
220 [i,g,i,i,v,i],
221 [i,g,i,i,v,v],
222 [i,g,i,v,g,g],
223 [i,g,i,v,g,i],
224 [i,g,i,v,g,v],
225 [i,g,i,v,i,g],
226 [i,g,i,v,i,i],
227 [i,g,i,v,i,v]|R]) :- r6_7(R) .
228 r6_7([
229 [i,g,i,v,v,g],
230 [i,g,i,v,v,i],
231 [i,g,i,v,v,v],
232 [i,g,v,g,g,g],
233 [i,g,v,g,g,i],
234 [i,g,v,g,g,v],
235 [i,g,v,g,i,g]|R]) :- r6_8(R) .
236 r6_8([
237 [i,g,v,g,i,i],
238 [i,g,v,g,i,v],
239 [i,g,v,g,v,g],
240 [i,g,v,g,v,i],
241 [i,g,v,g,v,v],
242 [i,g,v,i,g,g]|R]) :- r6_9(R) .
243 r6_9([
244 [i,g,v,i,g,i],
245 [i,g,v,i,g,v],
246 [i,g,v,i,i,g],
247 [i,g,v,i,i,i],
248 [i,g,v,i,i,v],
249 [i,g,v,i,v,g],
250 [i,g,v,i,v,i]|R]) :- r6_10(R) .
251 r6_10([
252 [i,g,v,i,v,v],
253 [i,g,v,v,g,g],
254 [i,g,v,v,g,i],
255 [i,g,v,v,g,v],
256 [i,g,v,v,i,g],
257 [i,g,v,v,i,i],
258 [i,g,v,v,i,v]|R]) :- r6_11(R) .
259 r6_11([
260 [i,g,v,v,v,g],
261 [i,g,v,v,v,i],
262 [i,g,v,v,v,v],
263 [i,i,g,g,g,g],
264 [i,i,g,g,g,i],
265 [i,i,g,g,g,v],
266 [i,i,g,g,i,g],
267 [i,i,g,g,i,i]|R]) :- r6_12(R) .
268 r6_12([
269 [i,i,g,g,i,v],
270 [i,i,g,g,v,g],
271 [i,i,g,g,v,i],
272 [i,i,g,g,v,v],
273 [i,i,g,i,g,g],
274 [i,i,g,i,g,i],
275 [i,i,g,i,g,v]|R]) :- r6_13(R) .
276 r6_13([
277 [i,i,g,i,i,g],
278 [i,i,g,i,i,i],
279 [i,i,g,i,i,v],
280 [i,i,g,i,v,g],
281 [i,i,g,i,v,i],
282 [i,i,g,i,v,v],
283 [i,i,g,v,g,g]|R]) :- r6_14(R) .
284 r6_14([
285 [i,i,g,v,g,i],
286 [i,i,g,v,g,v],
287 [i,i,g,v,i,g],
288 [i,i,g,v,i,i],
289 [i,i,g,v,i,v],
290 [i,i,g,v,v,g],
291 [i,i,g,v,v,i],
292 [i,i,g,v,v,v]|R]) :- r6_15(R) .
293 r6_15([
294 [i,i,i,g,g,g],
295 [i,i,i,g,g,i],
296 [i,i,i,g,g,v],
297 [i,i,i,g,i,g],
298 [i,i,i,g,i,i],
299 [i,i,i,g,i,v],
300 [i,i,i,g,v,g],
301 [i,i,i,g,v,i]|R]) :- r6_16(R) .
302 r6_16([
303 [i,i,i,g,v,v],
304 [i,i,i,i,g,g],
305 [i,i,i,i,g,i],
306 [i,i,i,i,g,v],
307 [i,i,i,i,i,g],
308 [i,i,i,i,i,i],
309 [i,i,i,i,i,v]|R]) :- r6_17(R) .
310 r6_17([
311 [i,i,i,i,v,g],
312 [i,i,i,i,v,i],
313 [i,i,i,i,v,v],
314 [i,i,i,v,g,g],
315 [i,i,i,v,g,i],
316 [i,i,i,v,g,v],
317 [i,i,i,v,i,g]|R]) :- r6_18(R) .
318 r6_18([
319 [i,i,i,v,i,i],
320 [i,i,i,v,i,v],
321 [i,i,i,v,v,g],
322 [i,i,i,v,v,i],
323 [i,i,i,v,v,v],
324 [i,i,v,g,g,g],
325 [i,i,v,g,g,i]|R]) :- r6_19(R) .
326 r6_19([
327 [i,i,v,g,g,v],
328 [i,i,v,g,i,g],
329 [i,i,v,g,i,i],
330 [i,i,v,g,i,v],
331 [i,i,v,g,v,g],
332 [i,i,v,g,v,i],
333 [i,i,v,g,v,v],
334 [i,i,v,i,g,g]|R]) :- r6_21(R) .
335 r6_21([
336 [i,i,v,i,g,i],
337 [i,i,v,i,g,v],
338 [i,i,v,i,i,g],
339 [i,i,v,i,i,i],
340 [i,i,v,i,i,v],
341 [i,i,v,i,v,g],
342 [i,i,v,i,v,i]|R]) :- r6_31(R) .
343 r6_31([
344 [i,i,v,i,v,v],
345 [i,i,v,v,g,g],
346 [i,i,v,v,g,i],
347 [i,i,v,v,g,v],
348 [i,i,v,v,i,g],
349 [i,i,v,v,i,i],
350 [i,i,v,v,i,v]|R]) :- r6_41(R) .
351 r6_41([
352 [i,i,v,v,v,g],
353 [i,i,v,v,v,i],
354 [i,i,v,v,v,v],
355 [i,v,g,g,g,g],
356 [i,v,g,g,g,i],
357 [i,v,g,g,g,v],
358 [i,v,g,g,i,g],
359 [i,v,g,g,i,i]|R]) :- r6_51(R) .
360 r6_51([
361 [i,v,g,g,i,v],
362 [i,v,g,g,v,g],
363 [i,v,g,g,v,i],
364 [i,v,g,g,v,v],
365 [i,v,g,i,g,g],
366 [i,v,g,i,g,i],
367 [i,v,g,i,g,v],
368 [i,v,g,i,i,g]|R]) :- r6_61(R) .
369 r6_61([
370 [i,v,g,i,i,i],
371 [i,v,g,i,i,v],
372 [i,v,g,i,v,g],
373 [i,v,g,i,v,i],
374 [i,v,g,i,v,v],
375 [i,v,g,v,g,g],
376 [i,v,g,v,g,i]|R]) :- r6_71(R) .
377 r6_71([
378 [i,v,g,v,g,v],
379 [i,v,g,v,i,g],
380 [i,v,g,v,i,i],
381 [i,v,g,v,i,v],
382 [i,v,g,v,v,g]|R]) :- r6_81(R) .
383 r6_81([
384 [i,v,g,v,v,i],
385 [i,v,g,v,v,v],
386 [i,v,i,g,g,g],
387 [i,v,i,g,g,i],
388 [i,v,i,g,g,v],
389 [i,v,i,g,i,g],
390 [i,v,i,g,i,i]|R]) :- r6_91(R) .
391 r6_91([
392 [i,v,i,g,i,v],
393 [i,v,i,g,v,g],
394 [i,v,i,g,v,i],
395 [i,v,i,g,v,v],
396 [i,v,i,i,g,g],
397 [i,v,i,i,g,i],
398 [i,v,i,i,g,v]|R]) :- r6_111(R) .
399 r6_111([
400 [i,v,i,i,i,g],
401 [i,v,i,i,i,i],
402 [i,v,i,i,i,v],
403 [i,v,i,i,v,g],
404 [i,v,i,i,v,i],
405 [i,v,i,i,v,v]|R]) :- r6_221(R) .
406 r6_221([
407 [i,v,i,v,g,g],
408 [i,v,i,v,g,i],
409 [i,v,i,v,g,v],
410 [i,v,i,v,i,g],
411 [i,v,i,v,i,i],
412 [i,v,i,v,i,v]|R]) :- r6_331(R) .
413 r6_331([
414 [i,v,i,v,v,g],
415 [i,v,i,v,v,i],
416 [i,v,i,v,v,v],
417 [i,v,v,g,g,g],
418 [i,v,v,g,g,i],
419 [i,v,v,g,g,v]|R]) :- r6_441(R) .
420 r6_441([
421 [i,v,v,g,i,g],
422 [i,v,v,g,i,i],
423 [i,v,v,g,i,v],
424 [i,v,v,g,v,g],
425 [i,v,v,g,v,i],
426 [i,v,v,g,v,v],
427 [i,v,v,i,g,g]|R]) :- r6_551(R) .
428 r6_551([
429 [i,v,v,i,g,i],
430 [i,v,v,i,g,v],
431 [i,v,v,i,i,g],
432 [i,v,v,i,i,i],
433 [i,v,v,i,i,v],
434 [i,v,v,i,v,g]|R]) :- r6_661(R) .
435 r6_661([
436 [i,v,v,i,v,i],
437 [i,v,v,i,v,v],
438 [i,v,v,v,g,g],
439 [i,v,v,v,g,i],
440 [i,v,v,v,g,v],
441 [i,v,v,v,i,g]|R]) :- r6_771(R) .
442 r6_771([
443 [i,v,v,v,i,i],
444 [i,v,v,v,i,v],
445 [i,v,v,v,v,g],
446 [i,v,v,v,v,i],
447 [i,v,v,v,v,v]]) .
0 :- [exec].
1 :- [kalah_ox].
2 %:- import start_forest_view/1 from tables.
3 %?- start_forest_view(userout).
4
5 % Don't abstract -- no finite model.
6 ?- set_prolog_flag(max_table_subgoal_size,200000).
7 ?- set_prolog_flag(max_table_subgoal_size_action,error).
8 test :- exec,fail.
0 :- table(play_2 / 2) .
1 play_2([ _164 , _165 ], _309 ) :- initialize_3( _345 , _347 ) , _345 = [ _164 , _171 , _172 ] , displaygame_2( _388 , _390 ) , _388 = [ _171 , _172 ] , play_3( _429 , _431 ) , _429 = [ _171 , _172 , _165 ] , compute([[ _171 , _172 , _165 ],[ _171 , _172 ],[ _164 , _171 , _172 ]],[ _431 , _390 , _347 ],[ _164 , _165 ], _309 ) .
2 :- table(play_3 / 2) .
3 play_3([ _164 , _165 , _166 ], _268 ) :- gameover_3( _306 , _308 ) , _306 = [ _164 , _165 , _166 ] , announce_1( _349 , _351 ) , _349 = [ _166 ] , compute([[ _166 ],[ _164 , _165 , _166 ]],[ _351 , _308 ],[ _164 , _165 , _166 ], _268 ) .
4 play_3([ _164 , _165 , _166 ], _391 ) :- choosemove_3( _429 , _431 ) , _429 = [ _164 , _165 , _173 ] , move_3( _472 , _474 ) , _472 = [ _173 , _164 , _180 ] , displaygame_2( _515 , _517 ) , _515 = [ _180 , _165 ] , nextplayer_2( _556 , _558 ) , _556 = [ _165 , _192 ] , play_3( _597 , _599 ) , _597 = [ _180 , _192 , _166 ] , compute([[ _180 , _192 , _166 ],[ _165 , _192 ],[ _180 , _165 ],[ _173 , _164 , _180 ],[ _164 , _165 , _173 ]],[ _599 , _558 , _517 , _474 , _431 ],[ _164 , _165 , _166 ], _391 ) .
5 :- table(choosemove_3 / 2) .
6 choosemove_3([ _164 , _200 , _166 ], _343 ) :- iff_1( _381 , _383 ) , _381 = [ _200 ] , lookahead_1( _420 , _422 ) , _420 = [ _171 ] , iff_1( _459 , _461 ) , _459 = [ _260 ] , iff_1( _498 , _500 ) , _498 = [ _268 ] , alphabeta_6( _537 , _539 ) , _537 = [ _171 , _164 , _260 , _268 , _166 , _178 ] , compute([[ _171 , _164 , _260 , _268 , _166 , _178 ],[ _268 ],[ _260 ],[ _171 ],[ _200 ]],[ _539 , _500 , _461 , _422 , _383 ],[ _164 , _200 , _166 ], _343 ) .
7 choosemove_3([ _164 , _190 , _166 ], _246 ) :- iff_1( _284 , _286 ) , _284 = [ _190 ] , genlegal_1( _323 , _325 ) , _323 = [ _166 ] , compute([[ _166 ],[ _190 ]],[ _325 , _286 ],[ _164 , _190 , _166 ], _246 ) .
8 :- table(alphabeta_6 / 2) .
9 alphabeta_6([ _198 , _165 , _166 , _167 , _168 , _169 ], _270 ) :- iff_1( _314 , _316 ) , _314 = [ _198 ] , value_2( _353 , _355 ) , _353 = [ _165 , _169 ] , compute([[ _165 , _169 ],[ _198 ]],[ _355 , _316 ],[ _198 , _165 , _166 , _167 , _168 , _169 ], _270 ) .
10 alphabeta_6([ _164 , _165 , _166 , _167 , _168 , _169 ], _597 ) :- iff_1( _641 , _643 ) , _641 = [ _281 ] , myis_2( _680 , _682 ) , _680 = [ _164 , _281 ] , allmoves_2( _721 , _723 ) , _721 = [ _165 , _181 ] , iff_2( _762 , _764 ) , _762 = [ _337 , _167 ] , myis_2( _803 , _805 ) , _803 = [ _186 , _337 ] , iff_2( _844 , _846 ) , _844 = [ _368 , _166 ] , myis_2( _885 , _887 ) , _885 = [ _195 , _368 ] , iff_2( _926 , _928 ) , _926 = [ _399 , _164 ] , myis_2( _967 , _969 ) , _967 = [ _204 , _399 ] , iff_1( _1008 , _1010 ) , _1008 = [ _447 ] , iff_3( _1047 , _1049 ) , _1047 = [ _455 , _168 , _169 ] , evaluateandchoose_7( _1090 , _1092 ) , _1090 = [ _181 , _165 , _204 , _186 , _195 , _447 , _455 ] , compute([[ _181 , _165 , _204 , _186 , _195 , _447 , _455 ],[ _455 , _168 , _169 ],[ _447 ],[ _204 , _399 ],[ _399 , _164 ],[ _195 , _368 ],[ _368 , _166 ],[ _186 , _337 ],[ _337 , _167 ],[ _165 , _181 ],[ _164 , _281 ],[ _281 ]],[ _1092 , _1049 , _1010 , _969 , _928 , _887 , _846 , _805 , _764 , _723 , _682 , _643 ],[ _164 , _165 , _166 , _167 , _168 , _169 ], _597 ) .
11 :- table(allmoves_2 / 2) .
12 allmoves_2([ _164 , _190 ], _251 ) :- iff_2( _287 , _289 ) , _287 = [ _190 , _166 ] , move_2( _328 , _330 ) , _328 = [ _164 , _166 ] , compute([[ _164 , _166 ],[ _190 , _166 ]],[ _330 , _289 ],[ _164 , _190 ], _251 ) .
13 allmoves_2([ _164 , _196 ], _289 ) :- iff_3( _325 , _327 ) , _325 = [ _196 , _166 , _167 ] , move_2( _368 , _370 ) , _368 = [ _164 , _166 ] , allmoves_2( _409 , _411 ) , _409 = [ _164 , _167 ] , compute([[ _164 , _167 ],[ _164 , _166 ],[ _196 , _166 , _167 ]],[ _411 , _370 , _327 ],[ _164 , _196 ], _289 ) .
14 :- table(evaluateandchoose_7 / 2) .
15 evaluateandchoose_7([ _236 , _165 , _166 , _167 , _168 , _169 , _170 ], _486 ) :- iff_3( _532 , _534 ) , _532 = [ _236 , _171 , _172 ] , move_3( _575 , _577 ) , _575 = [ _171 , _165 , _179 ] , alphabeta_6( _618 , _620 ) , _618 = [ _166 , _179 , _167 , _168 , _188 , _189 ] , iff_2( _667 , _669 ) , _667 = [ _356 , _189 ] , myis_2( _708 , _710 ) , _708 = [ _194 , _356 ] , cutoff_9( _749 , _751 ) , _749 = [ _171 , _194 , _166 , _167 , _168 , _172 , _165 , _169 , _170 ] , compute([[ _171 , _194 , _166 , _167 , _168 , _172 , _165 , _169 , _170 ],[ _194 , _356 ],[ _356 , _189 ],[ _166 , _179 , _167 , _168 , _188 , _189 ],[ _171 , _165 , _179 ],[ _236 , _171 , _172 ]],[ _751 , _710 , _669 , _620 , _577 , _534 ],[ _236 , _165 , _166 , _167 , _168 , _169 , _170 ], _486 ) .
16 evaluateandchoose_7([ _197 , _162 , _163 , _164 , _165 , _166 , _215 ], _269 ) :- iff_1( _315 , _317 ) , _315 = [ _197 ] , iff_3( _354 , _356 ) , _354 = [ _215 , _166 , _164 ] , compute([[ _215 , _166 , _164 ],[ _197 ]],[ _356 , _317 ],[ _197 , _162 , _163 , _164 , _165 , _166 , _215 ], _269 ) .
17 :- table(cutoff_9 / 2) .
18 cutoff_9([ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _226 ], _297 ) :- iff_3( _347 , _349 ) , _347 = [ _226 , _164 , _165 ] , myis_2( _390 , _392 ) , _390 = [ _165 , _168 ] , compute([[ _165 , _168 ],[ _226 , _164 , _165 ]],[ _392 , _349 ],[ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _226 ], _297 ) .
19 cutoff_9([ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _172 ], _369 ) :- myis_2( _419 , _421 ) , _419 = [ _167 , _165 ] , myis_2( _460 , _462 ) , _460 = [ _165 , _168 ] , evaluateandchoose_7( _501 , _503 ) , _501 = [ _169 , _170 , _166 , _165 , _168 , _164 , _172 ] , compute([[ _169 , _170 , _166 , _165 , _168 , _164 , _172 ],[ _165 , _168 ],[ _167 , _165 ]],[ _503 , _462 , _421 ],[ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _172 ], _369 ) .
20 cutoff_9([ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _172 ], _334 ) :- myis_2( _384 , _386 ) , _384 = [ _165 , _167 ] , evaluateandchoose_7( _425 , _427 ) , _425 = [ _169 , _170 , _166 , _167 , _168 , _171 , _172 ] , compute([[ _169 , _170 , _166 , _167 , _168 , _171 , _172 ],[ _165 , _167 ]],[ _427 , _386 ],[ _164 , _165 , _166 , _167 , _168 , _169 , _170 , _171 , _172 ], _334 ) .
21 :- table(move_2 / 2) .
22 move_2([ _164 , _217 ], _373 ) :- iff_3( _409 , _411 ) , _409 = [ _217 , _166 , _167 ] , iff_1( _452 , _454 ) , _452 = [ _245 ] , member_2( _491 , _493 ) , _491 = [ _166 , _245 ] , stonesinhole_3( _532 , _534 ) , _532 = [ _166 , _164 , _192 ] , extendmove_4( _575 , _577 ) , _575 = [ _192 , _166 , _164 , _167 ] , compute([[ _192 , _166 , _164 , _167 ],[ _166 , _164 , _192 ],[ _166 , _245 ],[ _245 ],[ _217 , _166 , _167 ]],[ _577 , _534 , _493 , _454 , _411 ],[ _164 , _217 ], _373 ) .
23 move_2([ _196 , _204 ], _256 ) :- iff_4( _292 , _294 ) , _292 = [ _196 , _165 , _166 , _167 ] , iff_1( _337 , _339 ) , _337 = [ _204 ] , compute([[ _204 ],[ _196 , _165 , _166 , _167 ]],[ _339 , _294 ],[ _196 , _204 ], _256 ) .
24 :- table(member_2 / 2) .
25 member_2([ _161 , _183 ], _219 ) :- iff_3( _255 , _257 ) , _255 = [ _183 , _161 , _164 ] , compute([[ _183 , _161 , _164 ]],[ _257 ],[ _161 , _183 ], _219 ) .
26 member_2([ _164 , _190 ], _254 ) :- iff_3( _290 , _292 ) , _290 = [ _190 , _166 , _167 ] , member_2( _333 , _335 ) , _333 = [ _164 , _167 ] , compute([[ _164 , _167 ],[ _190 , _166 , _167 ]],[ _335 , _292 ],[ _164 , _190 ], _254 ) .
27 :- table(stonesinhole_3 / 2) .
28 stonesinhole_3([ _164 , _203 , _166 ], _329 ) :- iff_5( _367 , _369 ) , _367 = [ _203 , _168 , _169 , _170 , _171 ] , nthmember_3( _414 , _416 ) , _414 = [ _164 , _168 , _166 ] , iff_1( _457 , _459 ) , _457 = [ _263 ] , myis_2( _496 , _498 ) , _496 = [ _166 , _263 ] , compute([[ _166 , _263 ],[ _263 ],[ _164 , _168 , _166 ],[ _203 , _168 , _169 , _170 , _171 ]],[ _498 , _459 , _416 , _369 ],[ _164 , _203 , _166 ], _329 ) .
29 :- table(extendmove_4 / 2) .
30 extendmove_4([ _164 , _165 , _166 , _201 ], _283 ) :- iff_1( _323 , _325 ) , _323 = [ _201 ] , iff_2( _362 , _364 ) , _362 = [ _230 , _165 ] , myis_2( _403 , _405 ) , _403 = [ _164 , _230 ] , compute([[ _164 , _230 ],[ _230 , _165 ],[ _201 ]],[ _405 , _364 , _325 ],[ _164 , _165 , _166 , _201 ], _283 ) .
31 extendmove_4([ _164 , _165 , _166 , _167 ], _346 ) :- iff_2( _386 , _388 ) , _386 = [ _239 , _165 ] , myis_2( _427 , _429 ) , _427 = [ _164 , _239 ] , distributestones_4( _468 , _470 ) , _468 = [ _164 , _165 , _166 , _184 ] , move_2( _513 , _515 ) , _513 = [ _184 , _167 ] , compute([[ _184 , _167 ],[ _164 , _165 , _166 , _184 ],[ _164 , _239 ],[ _239 , _165 ]],[ _515 , _470 , _429 , _388 ],[ _164 , _165 , _166 , _167 ], _346 ) .
32 :- table(move_3 / 2) .
33 move_3([ _207 , _165 , _166 ], _354 ) :- iff_3( _392 , _394 ) , _392 = [ _207 , _167 , _168 ] , stonesinhole_3( _435 , _437 ) , _435 = [ _167 , _165 , _175 ] , distributestones_4( _478 , _480 ) , _478 = [ _175 , _167 , _165 , _183 ] , move_3( _523 , _525 ) , _523 = [ _168 , _183 , _166 ] , compute([[ _168 , _183 , _166 ],[ _175 , _167 , _165 , _183 ],[ _167 , _165 , _175 ],[ _207 , _167 , _168 ]],[ _525 , _480 , _437 , _394 ],[ _207 , _165 , _166 ], _354 ) .
34 move_3([ _189 , _165 , _166 ], _252 ) :- iff_1( _290 , _292 ) , _290 = [ _189 ] , swap_2( _329 , _331 ) , _329 = [ _165 , _166 ] , compute([[ _165 , _166 ],[ _189 ]],[ _331 , _292 ],[ _189 , _165 , _166 ], _252 ) .
35 :- table(distributestones_4 / 2) .
36 distributestones_4([ _164 , _165 , _166 , _167 ], _298 ) :- distributemyholes_5( _338 , _340 ) , _338 = [ _164 , _165 , _166 , _175 , _176 ] , distributeyourholes_3( _385 , _387 ) , _385 = [ _176 , _175 , _167 ] , compute([[ _176 , _175 , _167 ],[ _164 , _165 , _166 , _175 , _176 ]],[ _387 , _340 ],[ _164 , _165 , _166 , _167 ], _298 ) .
37 :- table(distributemyholes_5 / 2) .
38 distributemyholes_5([ _164 , _165 , _241 , _249 , _168 ], _515 ) :- iff_5( _557 , _559 ) , _557 = [ _241 , _170 , _171 , _172 , _173 ] , iff_5( _604 , _606 ) , _604 = [ _249 , _175 , _176 , _172 , _173 ] , iff_2( _651 , _653 ) , _651 = [ _282 , _165 ] , myis_2( _692 , _694 ) , _692 = [ _164 , _282 ] , pickupanddistribute_4( _733 , _735 ) , _733 = [ _165 , _164 , _170 , _175 ] , iff_2( _778 , _780 ) , _778 = [ _348 , _171 ] , myis_2( _819 , _821 ) , _819 = [ _176 , _348 ] , iff_3( _860 , _862 ) , _860 = [ _378 , _164 , _165 ] , myis_2( _903 , _905 ) , _903 = [ _168 , _378 ] , compute([[ _168 , _378 ],[ _378 , _164 , _165 ],[ _176 , _348 ],[ _348 , _171 ],[ _165 , _164 , _170 , _175 ],[ _164 , _282 ],[ _282 , _165 ],[ _249 , _175 , _176 , _172 , _173 ],[ _241 , _170 , _171 , _172 , _173 ]],[ _905 , _862 , _821 , _780 , _735 , _694 , _653 , _606 , _559 ],[ _164 , _165 , _241 , _249 , _168 ], _515 ) .
39 distributemyholes_5([ _164 , _165 , _237 , _167 , _247 ], _501 ) :- iff_5( _543 , _545 ) , _543 = [ _237 , _170 , _171 , _172 , _173 ] , iff_1( _590 , _592 ) , _590 = [ _247 ] , pickupanddistribute_4( _629 , _631 ) , _629 = [ _165 , _164 , _170 , _181 ] , checkcapture_7( _674 , _676 ) , _674 = [ _165 , _164 , _181 , _189 , _172 , _191 , _192 ] , updatekalah_5( _725 , _727 ) , _725 = [ _192 , _165 , _164 , _171 , _201 ] , iff_5( _772 , _774 ) , _772 = [ _400 , _189 , _201 , _191 , _173 ] , checkiffinished_2( _819 , _821 ) , _819 = [ _400 , _167 ] , compute([[ _400 , _167 ],[ _400 , _189 , _201 , _191 , _173 ],[ _192 , _165 , _164 , _171 , _201 ],[ _165 , _164 , _181 , _189 , _172 , _191 , _192 ],[ _165 , _164 , _170 , _181 ],[ _247 ],[ _237 , _170 , _171 , _172 , _173 ]],[ _821 , _774 , _727 , _676 , _631 , _592 , _545 ],[ _164 , _165 , _237 , _167 , _247 ], _501 ) .
40 :- table(checkcapture_7 / 2) .
41 checkcapture_7([ _164 , _165 , _166 , _167 , _168 , _169 , _170 ], _632 ) :- iff_3( _678 , _680 ) , _678 = [ _290 , _164 , _165 ] , myis_2( _721 , _723 ) , _721 = [ _175 , _290 ] , iff_2( _762 , _764 ) , _762 = [ _321 , _175 ] , myis_2( _803 , _805 ) , _803 = [ _184 , _321 ] , nthmember_3( _844 , _846 ) , _844 = [ _184 , _168 , _195 ] , iff_1( _887 , _889 ) , _887 = [ _382 ] , myis_2( _926 , _928 ) , _926 = [ _195 , _382 ] , iff_1( _967 , _969 ) , _967 = [ _419 ] , nsubstitute_4( _1006 , _1008 ) , _1006 = [ _184 , _166 , _419 , _167 ] , iff_1( _1051 , _1053 ) , _1051 = [ _460 ] , nsubstitute_4( _1090 , _1092 ) , _1090 = [ _175 , _168 , _460 , _169 ] , iff_2( _1135 , _1137 ) , _1135 = [ _494 , _195 ] , myis_2( _1176 , _1178 ) , _1176 = [ _170 , _494 ] , compute([[ _170 , _494 ],[ _494 , _195 ],[ _175 , _168 , _460 , _169 ],[ _460 ],[ _184 , _166 , _419 , _167 ],[ _419 ],[ _195 , _382 ],[ _382 ],[ _184 , _168 , _195 ],[ _184 , _321 ],[ _321 , _175 ],[ _175 , _290 ],[ _290 , _164 , _165 ]],[ _1178 , _1137 , _1092 , _1053 , _1008 , _969 , _928 , _889 , _846 , _805 , _764 , _723 , _680 ],[ _164 , _165 , _166 , _167 , _168 , _169 , _170 ], _632 ) .
42 checkcapture_7([ _161 , _162 , _198 , _163 , _208 , _165 , _218 ], _267 ) :- iffequal_2( _313 , _315 ) , _313 = [ _198 , _163 ] , iffequal_2( _354 , _356 ) , _354 = [ _208 , _165 ] , iff_1( _395 , _397 ) , _395 = [ _218 ] , compute([[ _218 ],[ _208 , _165 ],[ _198 , _163 ]],[ _397 , _356 , _315 ],[ _161 , _162 , _198 , _163 , _208 , _165 , _218 ], _267 ) .
43 :- table(checkiffinished_2 / 2) .
44 checkiffinished_2([ _210 , _218 ], _388 ) :- iff_5( _424 , _426 ) , _424 = [ _210 , _167 , _168 , _169 , _170 ] , iff_4( _471 , _473 ) , _471 = [ _218 , _167 , _168 , _175 ] , zero_1( _516 , _518 ) , _516 = [ _167 ] , sumlist_2( _555 , _557 ) , _555 = [ _169 , _186 ] , iff_3( _596 , _598 ) , _596 = [ _290 , _170 , _186 ] , myis_2( _639 , _641 ) , _639 = [ _175 , _290 ] , compute([[ _175 , _290 ],[ _290 , _170 , _186 ],[ _169 , _186 ],[ _167 ],[ _218 , _167 , _168 , _175 ],[ _210 , _167 , _168 , _169 , _170 ]],[ _641 , _598 , _557 , _518 , _473 , _426 ],[ _210 , _218 ], _388 ) .
45 checkiffinished_2([ _210 , _218 ], _388 ) :- iff_5( _424 , _426 ) , _424 = [ _210 , _167 , _168 , _169 , _170 ] , iff_4( _471 , _473 ) , _471 = [ _218 , _169 , _173 , _170 ] , zero_1( _516 , _518 ) , _516 = [ _169 ] , sumlist_2( _555 , _557 ) , _555 = [ _167 , _186 ] , iff_3( _596 , _598 ) , _596 = [ _290 , _168 , _186 ] , myis_2( _639 , _641 ) , _639 = [ _173 , _290 ] , compute([[ _173 , _290 ],[ _290 , _168 , _186 ],[ _167 , _186 ],[ _169 ],[ _218 , _169 , _173 , _170 ],[ _210 , _167 , _168 , _169 , _170 ]],[ _641 , _598 , _557 , _518 , _473 , _426 ],[ _210 , _218 ], _388 ) .
46 checkiffinished_2([ _179 , _161 ], _205 ) :- iffequal_2( _241 , _243 ) , _241 = [ _179 , _161 ] , compute([[ _179 , _161 ]],[ _243 ],[ _179 , _161 ], _205 ) .
47 :- table(updatekalah_5 / 2) .
48 updatekalah_5([ _198 , _165 , _166 , _210 , _167 ], _302 ) :- iff_1( _344 , _346 ) , _344 = [ _198 ] , iffequal_2( _383 , _385 ) , _383 = [ _210 , _167 ] , iff_2( _424 , _426 ) , _424 = [ _242 , _166 ] , myis_2( _465 , _467 ) , _465 = [ _165 , _242 ] , compute([[ _165 , _242 ],[ _242 , _166 ],[ _210 , _167 ],[ _198 ]],[ _467 , _426 , _385 , _346 ],[ _198 , _165 , _166 , _210 , _167 ], _302 ) .
49 updatekalah_5([ _207 , _165 , _166 , _167 , _168 ], _349 ) :- iff_1( _391 , _393 ) , _391 = [ _207 ] , iff_2( _430 , _432 ) , _430 = [ _246 , _166 ] , myis_2( _471 , _473 ) , _471 = [ _165 , _246 ] , iff_2( _512 , _514 ) , _512 = [ _276 , _167 ] , myis_2( _553 , _555 ) , _553 = [ _168 , _276 ] , compute([[ _168 , _276 ],[ _276 , _167 ],[ _165 , _246 ],[ _246 , _166 ],[ _207 ]],[ _555 , _514 , _473 , _432 , _393 ],[ _207 , _165 , _166 , _167 , _168 ], _349 ) .
50 updatekalah_5([ _164 , _165 , _166 , _167 , _168 ], _327 ) :- iff_1( _369 , _371 ) , _369 = [ _237 ] , myis_2( _408 , _410 ) , _408 = [ _164 , _237 ] , iff_3( _449 , _451 ) , _449 = [ _267 , _167 , _164 ] , myis_2( _492 , _494 ) , _492 = [ _168 , _267 ] , compute([[ _168 , _267 ],[ _267 , _167 , _164 ],[ _164 , _237 ],[ _237 ]],[ _494 , _451 , _410 , _371 ],[ _164 , _165 , _166 , _167 , _168 ], _327 ) .
51 :- table(distributeyourholes_3 / 2) .
52 distributeyourholes_3([ _182 , _190 , _162 ], _230 ) :- iff_1( _268 , _270 ) , _268 = [ _182 ] , iffequal_2( _307 , _309 ) , _307 = [ _190 , _162 ] , compute([[ _190 , _162 ],[ _182 ]],[ _309 , _270 ],[ _182 , _190 , _162 ], _230 ) .
53 distributeyourholes_3([ _164 , _219 , _227 ], _448 ) :- iff_5( _486 , _488 ) , _486 = [ _219 , _168 , _169 , _170 , _171 ] , iff_5( _533 , _535 ) , _533 = [ _227 , _168 , _169 , _175 , _171 ] , iff_1( _580 , _582 ) , _580 = [ _254 ] , myis_2( _619 , _621 ) , _619 = [ _254 , _164 ] , iff_1( _660 , _662 ) , _660 = [ _287 ] , myis_2( _699 , _701 ) , _699 = [ _164 , _287 ] , nonzero_1( _740 , _742 ) , _740 = [ _168 ] , distribute_3( _779 , _781 ) , _779 = [ _164 , _170 , _175 ] , compute([[ _164 , _170 , _175 ],[ _168 ],[ _164 , _287 ],[ _287 ],[ _254 , _164 ],[ _254 ],[ _227 , _168 , _169 , _175 , _171 ],[ _219 , _168 , _169 , _170 , _171 ]],[ _781 , _742 , _701 , _662 , _621 , _582 , _535 , _488 ],[ _164 , _219 , _227 ], _448 ) .
54 distributeyourholes_3([ _164 , _230 , _238 ], _546 ) :- iff_5( _584 , _586 ) , _584 = [ _230 , _168 , _169 , _170 , _171 ] , iff_5( _631 , _633 ) , _631 = [ _238 , _168 , _169 , _175 , _171 ] , iff_1( _678 , _680 ) , _678 = [ _267 ] , myis_2( _717 , _719 ) , _717 = [ _164 , _267 ] , iff_1( _758 , _760 ) , _758 = [ _298 ] , distribute_3( _797 , _799 ) , _797 = [ _298 , _170 , _175 ] , iff_2( _840 , _842 ) , _840 = [ _334 , _164 ] , myis_2( _881 , _883 ) , _881 = [ _194 , _334 ] , iff_1( _922 , _924 ) , _922 = [ _368 ] , iff_5( _961 , _963 ) , _961 = [ _376 , _168 , _169 , _175 , _171 ] , distributestones_4( _1008 , _1010 ) , _1008 = [ _194 , _368 , _376 , _203 ] , compute([[ _194 , _368 , _376 , _203 ],[ _376 , _168 , _169 , _175 , _171 ],[ _368 ],[ _194 , _334 ],[ _334 , _164 ],[ _298 , _170 , _175 ],[ _298 ],[ _164 , _267 ],[ _267 ],[ _238 , _168 , _169 , _175 , _171 ],[ _230 , _168 , _169 , _170 , _171 ]],[ _1010 , _963 , _924 , _883 , _842 , _799 , _760 , _719 , _680 , _633 , _586 ],[ _164 , _230 , _238 ], _546 ) .
55 distributeyourholes_3([ _164 , _218 , _226 ], _400 ) :- iff_5( _438 , _440 ) , _438 = [ _218 , _168 , _169 , _170 , _171 ] , iff_4( _485 , _487 ) , _485 = [ _226 , _168 , _169 , _176 ] , zero_1( _530 , _532 ) , _530 = [ _168 ] , sumlist_2( _569 , _571 ) , _569 = [ _170 , _187 ] , iff_4( _610 , _612 ) , _610 = [ _299 , _164 , _187 , _171 ] , myis_2( _655 , _657 ) , _655 = [ _176 , _299 ] , compute([[ _176 , _299 ],[ _299 , _164 , _187 , _171 ],[ _170 , _187 ],[ _168 ],[ _226 , _168 , _169 , _176 ],[ _218 , _168 , _169 , _170 , _171 ]],[ _657 , _612 , _571 , _532 , _487 , _440 ],[ _164 , _218 , _226 ], _400 ) .
56 :- table(pickupanddistribute_4 / 2) .
57 pickupanddistribute_4([ _197 , _165 , _207 , _215 ], _315 ) :- iff_1( _355 , _357 ) , _355 = [ _197 ] , iff_3( _394 , _396 ) , _394 = [ _207 , _168 , _169 ] , iff_2( _437 , _439 ) , _437 = [ _215 , _171 ] , distribute_3( _478 , _480 ) , _478 = [ _165 , _169 , _171 ] , compute([[ _165 , _169 , _171 ],[ _215 , _171 ],[ _207 , _168 , _169 ],[ _197 ]],[ _480 , _439 , _396 , _357 ],[ _197 , _165 , _207 , _215 ], _315 ) .
58 pickupanddistribute_4([ _164 , _165 , _217 , _225 ], _416 ) :- iff_3( _456 , _458 ) , _456 = [ _217 , _168 , _169 ] , iff_2( _499 , _501 ) , _499 = [ _225 , _171 ] , iff_1( _540 , _542 ) , _540 = [ _255 ] , myis_2( _579 , _581 ) , _579 = [ _164 , _255 ] , iff_2( _620 , _622 ) , _620 = [ _286 , _164 ] , myis_2( _661 , _663 ) , _661 = [ _182 , _286 ] , pickupanddistribute_4( _702 , _704 ) , _702 = [ _182 , _165 , _169 , _171 ] , compute([[ _182 , _165 , _169 , _171 ],[ _182 , _286 ],[ _286 , _164 ],[ _164 , _255 ],[ _255 ],[ _225 , _171 ],[ _217 , _168 , _169 ]],[ _704 , _663 , _622 , _581 , _542 , _501 , _458 ],[ _164 , _165 , _217 , _225 ], _416 ) .
59 :- table(distribute_3 / 2) .
60 distribute_3([ _182 , _190 , _162 ], _230 ) :- iff_1( _268 , _270 ) , _268 = [ _182 ] , iffequal_2( _307 , _309 ) , _307 = [ _190 , _162 ] , compute([[ _190 , _162 ],[ _182 ]],[ _309 , _270 ],[ _182 , _190 , _162 ], _230 ) .
61 distribute_3([ _164 , _220 , _228 ], _467 ) :- iff_3( _505 , _507 ) , _505 = [ _220 , _167 , _168 ] , iff_3( _548 , _550 ) , _548 = [ _228 , _169 , _170 ] , iff_1( _591 , _593 ) , _591 = [ _257 ] , myis_2( _630 , _632 ) , _630 = [ _164 , _257 ] , iff_2( _671 , _673 ) , _671 = [ _288 , _164 ] , myis_2( _712 , _714 ) , _712 = [ _181 , _288 ] , iff_2( _753 , _755 ) , _753 = [ _319 , _167 ] , myis_2( _794 , _796 ) , _794 = [ _169 , _319 ] , distribute_3( _835 , _837 ) , _835 = [ _181 , _168 , _170 ] , compute([[ _181 , _168 , _170 ],[ _169 , _319 ],[ _319 , _167 ],[ _181 , _288 ],[ _288 , _164 ],[ _164 , _257 ],[ _257 ],[ _228 , _169 , _170 ],[ _220 , _167 , _168 ]],[ _837 , _796 , _755 , _714 , _673 , _632 , _593 , _550 , _507 ],[ _164 , _220 , _228 ], _467 ) .
62 distribute_3([ _161 , _184 , _192 ], _236 ) :- iff_1( _274 , _276 ) , _274 = [ _184 ] , iff_1( _313 , _315 ) , _313 = [ _192 ] , compute([[ _192 ],[ _184 ]],[ _315 , _276 ],[ _161 , _184 , _192 ], _236 ) .
63 :- table(value_2 / 2) .
64 value_2([ _194 , _165 ], _291 ) :- iff_5( _327 , _329 ) , _327 = [ _194 , _167 , _168 , _169 , _170 ] , iff_3( _374 , _376 ) , _374 = [ _223 , _168 , _170 ] , myis_2( _417 , _419 ) , _417 = [ _165 , _223 ] , compute([[ _165 , _223 ],[ _223 , _168 , _170 ],[ _194 , _167 , _168 , _169 , _170 ]],[ _419 , _376 , _329 ],[ _194 , _165 ], _291 ) .
65 :- table(gameover_3 / 2) .
66 gameover_3([ _202 , _165 , _212 ], _333 ) :- iff_2( _371 , _373 ) , _371 = [ _202 , _169 ] , iff_1( _412 , _414 ) , _412 = [ _212 ] , pieces_1( _451 , _453 ) , _451 = [ _176 ] , iff_2( _490 , _492 ) , _490 = [ _260 , _176 ] , myis_2( _531 , _533 ) , _531 = [ _169 , _260 ] , compute([[ _169 , _260 ],[ _260 , _176 ],[ _176 ],[ _212 ],[ _202 , _169 ]],[ _533 , _492 , _453 , _414 , _373 ],[ _202 , _165 , _212 ], _333 ) .
67 gameover_3([ _202 , _210 , _165 ], _336 ) :- iff_5( _374 , _376 ) , _374 = [ _202 , _168 , _169 , _170 , _171 ] , iffequal_2( _421 , _423 ) , _421 = [ _210 , _165 ] , pieces_1( _462 , _464 ) , _462 = [ _176 ] , iff_2( _501 , _503 ) , _501 = [ _260 , _176 ] , myis_2( _542 , _544 ) , _542 = [ _169 , _260 ] , compute([[ _169 , _260 ],[ _260 , _176 ],[ _176 ],[ _210 , _165 ],[ _202 , _168 , _169 , _170 , _171 ]],[ _544 , _503 , _464 , _423 , _376 ],[ _202 , _210 , _165 ], _336 ) .
68 gameover_3([ _208 , _165 , _166 ], _358 ) :- iff_5( _396 , _398 ) , _396 = [ _208 , _168 , _169 , _170 , _171 ] , pieces_1( _443 , _445 ) , _443 = [ _176 ] , iff_2( _482 , _484 ) , _482 = [ _261 , _176 ] , myis_2( _523 , _525 ) , _523 = [ _171 , _261 ] , nextplayer_2( _564 , _566 ) , _564 = [ _165 , _166 ] , compute([[ _165 , _166 ],[ _171 , _261 ],[ _261 , _176 ],[ _176 ],[ _208 , _168 , _169 , _170 , _171 ]],[ _566 , _525 , _484 , _445 , _398 ],[ _208 , _165 , _166 ], _358 ) .
69 :- table(announce_1 / 2) .
70 announce_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
71 announce_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
72 announce_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
73 :- table(nthmember_3 / 2) .
74 nthmember_3([ _164 , _209 , _166 ], _380 ) :- iff_3( _418 , _420 ) , _418 = [ _209 , _167 , _168 ] , iff_1( _461 , _463 ) , _461 = [ _240 ] , myis_2( _500 , _502 ) , _500 = [ _164 , _240 ] , iff_2( _541 , _543 ) , _541 = [ _271 , _164 ] , myis_2( _582 , _584 ) , _582 = [ _179 , _271 ] , nthmember_3( _623 , _625 ) , _623 = [ _179 , _168 , _166 ] , compute([[ _179 , _168 , _166 ],[ _179 , _271 ],[ _271 , _164 ],[ _164 , _240 ],[ _240 ],[ _209 , _167 , _168 ]],[ _625 , _584 , _543 , _502 , _463 , _420 ],[ _164 , _209 , _166 ], _380 ) .
75 nthmember_3([ _184 , _192 , _164 ], _244 ) :- iff_1( _282 , _284 ) , _282 = [ _184 ] , iff_3( _321 , _323 ) , _321 = [ _192 , _164 , _165 ] , compute([[ _192 , _164 , _165 ],[ _184 ]],[ _323 , _284 ],[ _184 , _192 , _164 ], _244 ) .
76 :- table(nsubstitute_4 / 2) .
77 nsubstitute_4([ _189 , _197 , _163 , _207 ], _277 ) :- iff_1( _317 , _319 ) , _317 = [ _189 ] , iff_3( _356 , _358 ) , _356 = [ _197 , _165 , _166 ] , iff_3( _399 , _401 ) , _399 = [ _207 , _163 , _166 ] , compute([[ _207 , _163 , _166 ],[ _197 , _165 , _166 ],[ _189 ]],[ _401 , _358 , _319 ],[ _189 , _197 , _163 , _207 ], _277 ) .
78 nsubstitute_4([ _164 , _215 , _166 , _225 ], _419 ) :- iff_3( _459 , _461 ) , _459 = [ _215 , _168 , _169 ] , iff_3( _502 , _504 ) , _502 = [ _225 , _168 , _171 ] , iff_1( _545 , _547 ) , _545 = [ _255 ] , myis_2( _584 , _586 ) , _584 = [ _164 , _255 ] , iff_2( _625 , _627 ) , _625 = [ _286 , _164 ] , myis_2( _666 , _668 ) , _666 = [ _182 , _286 ] , nsubstitute_4( _707 , _709 ) , _707 = [ _182 , _169 , _166 , _171 ] , compute([[ _182 , _169 , _166 , _171 ],[ _182 , _286 ],[ _286 , _164 ],[ _164 , _255 ],[ _255 ],[ _225 , _168 , _171 ],[ _215 , _168 , _169 ]],[ _709 , _668 , _627 , _586 , _547 , _504 , _461 ],[ _164 , _215 , _166 , _225 ], _419 ) .
79 :- table(nextplayer_2 / 2) .
80 nextplayer_2([ _179 , _187 ], _230 ) :- iff_1( _266 , _268 ) , _266 = [ _179 ] , iff_1( _305 , _307 ) , _305 = [ _187 ] , compute([[ _187 ],[ _179 ]],[ _307 , _268 ],[ _179 , _187 ], _230 ) .
81 nextplayer_2([ _179 , _187 ], _230 ) :- iff_1( _266 , _268 ) , _266 = [ _179 ] , iff_1( _305 , _307 ) , _305 = [ _187 ] , compute([[ _187 ],[ _179 ]],[ _307 , _268 ],[ _179 , _187 ], _230 ) .
82 :- table(legal_1 / 2) .
83 legal_1([ _196 ], _350 ) :- iff_3( _384 , _386 ) , _384 = [ _196 , _165 , _166 ] , iff_1( _427 , _429 ) , _427 = [ _221 ] , myis_2( _466 , _468 ) , _466 = [ _221 , _165 ] , iff_1( _507 , _509 ) , _507 = [ _254 ] , myis_2( _546 , _548 ) , _546 = [ _165 , _254 ] , legal_1( _587 , _589 ) , _587 = [ _166 ] , compute([[ _166 ],[ _165 , _254 ],[ _254 ],[ _221 , _165 ],[ _221 ],[ _196 , _165 , _166 ]],[ _589 , _548 , _509 , _468 , _429 , _386 ],[ _196 ], _350 ) .
84 legal_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
85 :- table(genlegal_1 / 2) .
86 genlegal_1([ _202 ], _308 ) :- iff_3( _342 , _344 ) , _342 = [ _202 , _165 , _166 ] , iff_1( _385 , _387 ) , _385 = [ _229 ] , member_2( _424 , _426 ) , _424 = [ _165 , _229 ] , genlegal_1( _465 , _467 ) , _465 = [ _166 ] , compute([[ _166 ],[ _165 , _229 ],[ _229 ],[ _202 , _165 , _166 ]],[ _467 , _426 , _387 , _344 ],[ _202 ], _308 ) .
87 genlegal_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
88 :- table(swap_2 / 2) .
89 swap_2([ _189 , _197 ], _264 ) :- iff_5( _300 , _302 ) , _300 = [ _189 , _164 , _165 , _166 , _167 ] , iff_5( _347 , _349 ) , _347 = [ _197 , _166 , _167 , _164 , _165 ] , compute([[ _197 , _166 , _167 , _164 , _165 ],[ _189 , _164 , _165 , _166 , _167 ]],[ _349 , _302 ],[ _189 , _197 ], _264 ) .
90 :- table(displaygame_2 / 2) .
91 displaygame_2([ _164 , _187 ], _240 ) :- iff_1( _276 , _278 ) , _276 = [ _187 ] , show_1( _315 , _317 ) , _315 = [ _164 ] , compute([[ _164 ],[ _187 ]],[ _317 , _278 ],[ _164 , _187 ], _240 ) .
92 displaygame_2([ _164 , _193 ], _275 ) :- iff_1( _311 , _313 ) , _311 = [ _193 ] , swap_2( _350 , _352 ) , _350 = [ _164 , _171 ] , show_1( _391 , _393 ) , _391 = [ _171 ] , compute([[ _171 ],[ _164 , _171 ],[ _193 ]],[ _393 , _352 , _313 ],[ _164 , _193 ], _275 ) .
93 :- table(show_1 / 2) .
94 show_1([ _204 ], _350 ) :- iff_5( _384 , _386 ) , _384 = [ _204 , _166 , _167 , _168 , _169 ] , reverse_2( _431 , _433 ) , _431 = [ _166 , _175 ] , writestones_1( _472 , _474 ) , _472 = [ _175 ] , writekalahs_2( _511 , _513 ) , _511 = [ _167 , _169 ] , writestones_1( _552 , _554 ) , _552 = [ _168 ] , compute([[ _168 ],[ _167 , _169 ],[ _175 ],[ _166 , _175 ],[ _204 , _166 , _167 , _168 , _169 ]],[ _554 , _513 , _474 , _433 , _386 ],[ _204 ], _350 ) .
95 :- table(writestones_1 / 2) .
96 writestones_1([ _164 ], _215 ) :- displayholes_1( _249 , _251 ) , _249 = [ _164 ] , compute([[ _164 ]],[ _251 ],[ _164 ], _215 ) .
97 :- table(displayholes_1 / 2) .
98 displayholes_1([ _189 ], _271 ) :- iff_3( _305 , _307 ) , _305 = [ _189 , _165 , _166 ] , writepile_1( _348 , _350 ) , _348 = [ _165 ] , displayholes_1( _387 , _389 ) , _387 = [ _166 ] , compute([[ _166 ],[ _165 ],[ _189 , _165 , _166 ]],[ _389 , _350 , _307 ],[ _189 ], _271 ) .
99 displayholes_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
100 :- table(writepile_1 / 2) .
101 writepile_1([ _164 ], _269 ) :- iff_1( _303 , _305 ) , _303 = [ _209 ] , myis_2( _342 , _344 ) , _342 = [ _164 , _209 ] , wr_1( _383 , _385 ) , _383 = [ _164 ] , compute([[ _164 ],[ _164 , _209 ],[ _209 ]],[ _385 , _344 , _305 ],[ _164 ], _269 ) .
102 writepile_1([ _164 ], _269 ) :- iff_1( _303 , _305 ) , _303 = [ _209 ] , myis_2( _342 , _344 ) , _342 = [ _164 , _209 ] , wr_1( _383 , _385 ) , _383 = [ _164 ] , compute([[ _164 ],[ _164 , _209 ],[ _209 ]],[ _385 , _344 , _305 ],[ _164 ], _269 ) .
103 :- table(writekalahs_2 / 2) .
104 writekalahs_2([ _164 , _165 ], _250 ) :- wr_1( _286 , _288 ) , _286 = [ _164 ] , wr_1( _325 , _327 ) , _325 = [ _165 ] , compute([[ _165 ],[ _164 ]],[ _327 , _288 ],[ _164 , _165 ], _250 ) .
105 :- table(zero_1 / 2) .
106 zero_1([ _188 ], _217 ) :- iff_1( _251 , _253 ) , _251 = [ _188 ] , compute([[ _188 ]],[ _253 ],[ _188 ], _217 ) .
107 :- table(nonzero_1 / 2) .
108 nonzero_1([ _164 ], _252 ) :- iff_1( _286 , _288 ) , _286 = [ _215 ] , myis_2( _325 , _327 ) , _325 = [ _164 , _215 ] , compute([[ _164 , _215 ],[ _215 ]],[ _327 , _288 ],[ _164 ], _252 ) .
109 :- table(reverse_2 / 2) .
110 reverse_2([ _164 , _165 ], _252 ) :- iff_1( _288 , _290 ) , _288 = [ _212 ] , rev_3( _327 , _329 ) , _327 = [ _164 , _212 , _165 ] , compute([[ _164 , _212 , _165 ],[ _212 ]],[ _329 , _290 ],[ _164 , _165 ], _252 ) .
111 :- table(rev_3 / 2) .
112 rev_3([ _182 , _190 , _162 ], _230 ) :- iff_1( _268 , _270 ) , _268 = [ _182 ] , iffequal_2( _307 , _309 ) , _307 = [ _190 , _162 ] , compute([[ _190 , _162 ],[ _182 ]],[ _309 , _270 ],[ _182 , _190 , _162 ], _230 ) .
113 rev_3([ _194 , _165 , _166 ], _293 ) :- iff_3( _331 , _333 ) , _331 = [ _194 , _167 , _168 ] , iff_3( _374 , _376 ) , _374 = [ _228 , _167 , _165 ] , rev_3( _417 , _419 ) , _417 = [ _168 , _228 , _166 ] , compute([[ _168 , _228 , _166 ],[ _228 , _167 , _165 ],[ _194 , _167 , _168 ]],[ _419 , _376 , _333 ],[ _194 , _165 , _166 ], _293 ) .
114 :- table(sumlist_2 / 2) .
115 sumlist_2([ _164 , _165 ], _252 ) :- iff_1( _288 , _290 ) , _288 = [ _212 ] , sumlist_3( _327 , _329 ) , _327 = [ _164 , _212 , _165 ] , compute([[ _164 , _212 , _165 ],[ _212 ]],[ _329 , _290 ],[ _164 , _165 ], _252 ) .
116 :- table(sumlist_3 / 2) .
117 sumlist_3([ _182 , _190 , _162 ], _230 ) :- iff_1( _268 , _270 ) , _268 = [ _182 ] , iffequal_2( _307 , _309 ) , _307 = [ _190 , _162 ] , compute([[ _190 , _162 ],[ _182 ]],[ _309 , _270 ],[ _182 , _190 , _162 ], _230 ) .
118 sumlist_3([ _201 , _165 , _166 ], _326 ) :- iff_3( _364 , _366 ) , _364 = [ _201 , _167 , _168 ] , iff_2( _407 , _409 ) , _407 = [ _234 , _165 ] , myis_2( _448 , _450 ) , _448 = [ _173 , _234 ] , sumlist_3( _489 , _491 ) , _489 = [ _168 , _173 , _166 ] , compute([[ _168 , _173 , _166 ],[ _173 , _234 ],[ _234 , _165 ],[ _201 , _167 , _168 ]],[ _491 , _450 , _409 , _366 ],[ _201 , _165 , _166 ], _326 ) .
119 :- table(lookahead_1 / 2) .
120 lookahead_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
121 lookahead_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
122 :- table(initialize_3 / 2) .
123 initialize_3([ _187 , _195 , _203 ], _260 ) :- iff_1( _298 , _300 ) , _298 = [ _187 ] , iff_1( _337 , _339 ) , _337 = [ _195 ] , iff_1( _376 , _378 ) , _376 = [ _203 ] , compute([[ _203 ],[ _195 ],[ _187 ]],[ _378 , _339 , _300 ],[ _187 , _195 , _203 ], _260 ) .
124 initialize_3([ _187 , _195 , _203 ], _260 ) :- iff_1( _298 , _300 ) , _298 = [ _187 ] , iff_1( _337 , _339 ) , _337 = [ _195 ] , iff_1( _376 , _378 ) , _376 = [ _203 ] , compute([[ _203 ],[ _195 ],[ _187 ]],[ _378 , _339 , _300 ],[ _187 , _195 , _203 ], _260 ) .
125 :- table(pieces_1 / 2) .
126 pieces_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
127 pieces_1([ _176 ], _205 ) :- iff_1( _239 , _241 ) , _239 = [ _176 ] , compute([[ _176 ]],[ _241 ],[ _176 ], _205 ) .
128 :- table(myis_2 / 2) .
129 myis_2([ _179 , _187 ], _230 ) :- iff_1( _266 , _268 ) , _266 = [ _179 ] , iff_1( _305 , _307 ) , _305 = [ _187 ] , compute([[ _187 ],[ _179 ]],[ _307 , _268 ],[ _179 , _187 ], _230 ) .
130 :- table(wr_1 / 2) .
131 wr_1([ _161 ], _186 ) :- compute([],[],[ _161 ], _186 ) .
132 exec :- wr_1( _163 , _164 ) .
133 exec :- myis_2( _163 , _164 ) .
134 exec :- pieces_1( _163 , _164 ) .
135 exec :- initialize_3( _163 , _164 ) .
136 exec :- lookahead_1( _163 , _164 ) .
137 exec :- sumlist_3( _163 , _164 ) .
138 exec :- sumlist_2( _163 , _164 ) .
139 exec :- rev_3( _163 , _164 ) .
140 exec :- reverse_2( _163 , _164 ) .
141 exec :- nonzero_1( _163 , _164 ) .
142 exec :- zero_1( _163 , _164 ) .
143 exec :- writekalahs_2( _163 , _164 ) .
144 exec :- writepile_1( _163 , _164 ) .
145 exec :- displayholes_1( _163 , _164 ) .
146 exec :- writestones_1( _163 , _164 ) .
147 exec :- show_1( _163 , _164 ) .
148 exec :- swap_2( _163 , _164 ) .
149 exec :- displaygame_2( _163 , _164 ) .
150 exec :- member_2( _163 , _164 ) .
151 exec :- genlegal_1( _163 , _164 ) .
152 exec :- legal_1( _163 , _164 ) .
153 exec :- nextplayer_2( _163 , _164 ) .
154 exec :- nsubstitute_4( _163 , _164 ) .
155 exec :- nthmember_3( _163 , _164 ) .
156 exec :- announce_1( _163 , _164 ) .
157 exec :- gameover_3( _163 , _164 ) .
158 exec :- value_2( _163 , _164 ) .
159 exec :- distribute_3( _163 , _164 ) .
160 exec :- pickupanddistribute_4( _163 , _164 ) .
161 exec :- checkiffinished_2( _163 , _164 ) .
162 exec :- updatekalah_5( _163 , _164 ) .
163 exec :- checkcapture_7( _163 , _164 ) .
164 exec :- distributemyholes_5( _163 , _164 ) .
165 exec :- distributeyourholes_3( _163 , _164 ) .
166 exec :- distributestones_4( _163 , _164 ) .
167 exec :- stonesinhole_3( _163 , _164 ) .
168 exec :- move_3( _163 , _164 ) .
169 exec :- extendmove_4( _163 , _164 ) .
170 exec :- move_2( _163 , _164 ) .
171 exec :- allmoves_2( _163 , _164 ) .
172 exec :- cutoff_9( _163 , _164 ) .
173 exec :- evaluateandchoose_7( _163 , _164 ) .
174 exec :- alphabeta_6( _163 , _164 ) .
175 exec :- choosemove_3( _163 , _164 ) .
176 exec :- play_3( _163 , _164 ) .
177 exec :- play_2( _163 , _164 ) .
178
179
180 show :- wr_1( _163 , _164 ) , write(wr_1( _163 , _164 )) , nl , fail .
181 show :- myis_2( _163 , _164 ) , write(myis_2( _163 , _164 )) , nl , fail .
182 show :- pieces_1( _163 , _164 ) , write(pieces_1( _163 , _164 )) , nl , fail .
183 show :- initialize_3( _163 , _164 ) , write(initialize_3( _163 , _164 )) , nl , fail .
184 show :- lookahead_1( _163 , _164 ) , write(lookahead_1( _163 , _164 )) , nl , fail .
185 show :- sumlist_3( _163 , _164 ) , write(sumlist_3( _163 , _164 )) , nl , fail .
186 show :- sumlist_2( _163 , _164 ) , write(sumlist_2( _163 , _164 )) , nl , fail .
187 show :- rev_3( _163 , _164 ) , write(rev_3( _163 , _164 )) , nl , fail .
188 show :- reverse_2( _163 , _164 ) , write(reverse_2( _163 , _164 )) , nl , fail .
189 show :- nonzero_1( _163 , _164 ) , write(nonzero_1( _163 , _164 )) , nl , fail .
190 show :- zero_1( _163 , _164 ) , write(zero_1( _163 , _164 )) , nl , fail .
191 show :- writekalahs_2( _163 , _164 ) , write(writekalahs_2( _163 , _164 )) , nl , fail .
192 show :- writepile_1( _163 , _164 ) , write(writepile_1( _163 , _164 )) , nl , fail .
193 show :- displayholes_1( _163 , _164 ) , write(displayholes_1( _163 , _164 )) , nl , fail .
194 show :- writestones_1( _163 , _164 ) , write(writestones_1( _163 , _164 )) , nl , fail .
195 show :- show_1( _163 , _164 ) , write(show_1( _163 , _164 )) , nl , fail .
196 show :- displaygame_2( _163 , _164 ) , write(displaygame_2( _163 , _164 )) , nl , fail .
197 show :- swap_2( _163 , _164 ) , write(swap_2( _163 , _164 )) , nl , fail .
198 show :- genlegal_1( _163 , _164 ) , write(genlegal_1( _163 , _164 )) , nl , fail .
199 show :- legal_1( _163 , _164 ) , write(legal_1( _163 , _164 )) , nl , fail .
200 show :- nextplayer_2( _163 , _164 ) , write(nextplayer_2( _163 , _164 )) , nl , fail .
201 show :- nsubstitute_4( _163 , _164 ) , write(nsubstitute_4( _163 , _164 )) , nl , fail .
202 show :- nthmember_3( _163 , _164 ) , write(nthmember_3( _163 , _164 )) , nl , fail .
203 show :- announce_1( _163 , _164 ) , write(announce_1( _163 , _164 )) , nl , fail .
204 show :- gameover_3( _163 , _164 ) , write(gameover_3( _163 , _164 )) , nl , fail .
205 show :- value_2( _163 , _164 ) , write(value_2( _163 , _164 )) , nl , fail .
206 show :- distribute_3( _163 , _164 ) , write(distribute_3( _163 , _164 )) , nl , fail .
207 show :- pickupanddistribute_4( _163 , _164 ) , write(pickupanddistribute_4( _163 , _164 )) , nl , fail .
208 show :- distributeyourholes_3( _163 , _164 ) , write(distributeyourholes_3( _163 , _164 )) , nl , fail .
209 show :- updatekalah_5( _163 , _164 ) , write(updatekalah_5( _163 , _164 )) , nl , fail .
210 show :- checkiffinished_2( _163 , _164 ) , write(checkiffinished_2( _163 , _164 )) , nl , fail .
211 show :- checkcapture_7( _163 , _164 ) , write(checkcapture_7( _163 , _164 )) , nl , fail .
212 show :- distributemyholes_5( _163 , _164 ) , write(distributemyholes_5( _163 , _164 )) , nl , fail .
213 show :- distributestones_4( _163 , _164 ) , write(distributestones_4( _163 , _164 )) , nl , fail .
214 show :- move_3( _163 , _164 ) , write(move_3( _163 , _164 )) , nl , fail .
215 show :- extendmove_4( _163 , _164 ) , write(extendmove_4( _163 , _164 )) , nl , fail .
216 show :- stonesinhole_3( _163 , _164 ) , write(stonesinhole_3( _163 , _164 )) , nl , fail .
217 show :- member_2( _163 , _164 ) , write(member_2( _163 , _164 )) , nl , fail .
218 show :- move_2( _163 , _164 ) , write(move_2( _163 , _164 )) , nl , fail .
219 show :- cutoff_9( _163 , _164 ) , write(cutoff_9( _163 , _164 )) , nl , fail .
220 show :- evaluateandchoose_7( _163 , _164 ) , write(evaluateandchoose_7( _163 , _164 )) , nl , fail .
221 show :- allmoves_2( _163 , _164 ) , write(allmoves_2( _163 , _164 )) , nl , fail .
222 show :- alphabeta_6( _163 , _164 ) , write(alphabeta_6( _163 , _164 )) , nl , fail .
223 show :- choosemove_3( _163 , _164 ) , write(choosemove_3( _163 , _164 )) , nl , fail .
224 show :- play_3( _163 , _164 ) , write(play_3( _163 , _164 )) , nl , fail .
225 show :- play_2( _163 , _164 ) , write(play_2( _163 , _164 )) , nl , fail .
0
1 :- import xsb_error_get_tag/2 from error_handler.
2
3 %test:-
4 % test_fail,write('fail succeeded!').
5 test:-
6 catch(test_error,E,
7 ( xsb_error_get_tag(E,T),
8 numbervars(T, 0, _, [singletons(true)]),
9 format('~p~n', [error(T)])
10 )).
11
12 %test_fail:-
13 % abolish_all_tables,
14 % set_prolog_flag(max_table_subgoal_size,4),
15 % set_prolog_flag(max_table_subgoal_size_action,failure),
16 % p(_X).
17
18 test_error:-
19 abolish_all_tables,
20 set_prolog_flag(max_table_subgoal_size,4),
21 set_prolog_flag(max_table_subgoal_size_action,error),
22 p(_X).
23
24 :- table p/1.
25 p(X):- p(f(X)).
26
27
28
29
0 error(resource_error(tripwire(max_table_subgoal_size,xsb_test_calldepth:p(_))))
0 :- import close_open_tables/1 from machine.
1
2 :- set_prolog_flag(max_table_answer_size,25).
3 :- set_prolog_flag(max_table_subgoal_size,25).
4 :- set_prolog_flag(max_table_subgoal_size_action,error).
5
6 :- table p/1.
7 p(X):- X = f(X).
8
9 :- table r/1.
10 r(X):- make_term(100,X).
11
12 make_term(0,0):-!.
13 make_term(N,f(X)):-
14 N1 is N - 1,
15 make_term(N1,X).
16
17 test:- set_prolog_flag(unify_with_occurs_check,off),fail.
18 test:- catch(r(_X),error(_Type,context(_Msg,_)),writeln(caught_r)),fail.
19 test:- catch(p(_X),error(_Type,context(_Msg,_)),writeln(caught_p)),fail.
20 test:- X = f(X),catch(s(X),error(_Type,context(_Msg,_)),writeln(caught_s_1)),fail.
21 test:- make_term(100,X),catch(s(X),error(_Type,context(_Msg,_)),writeln(caught_s_2)),fail.
22 test:- close_open_tables(non_memory_error),fail.
23 test:- abolish_all_tables,fail.
24 test:- test_uwoc, fail.
25 test:- set_prolog_flag(unify_with_occurs_check,off),
26 set_prolog_flag(max_table_answer_size,infinite),
27 set_prolog_flag(max_table_subgoal_size,infinite),
28 fail.
29 test.
30
31 test_uwoc:- set_prolog_flag(unify_with_occurs_check,on),fail.
32 test_uwoc:- catch(r(_X),error(_Type,context(_Msg,_)),writeln(uwoc_caught_r)),fail.
33 test_uwoc:- catch(p(_X),error(_Type,context(_Msg,_)),writeln(uwoc_caught_p)),fail.
34 test_uwoc:- X = f(X),catch(s(X),error(_Type,context(_Msg,_)),writeln(uwoc_caught_s_1)),fail.
35 test_uwoc:- make_term(100,X),catch(s(X),error(_Type,context(_Msg,_)),writeln(uwoc_caught_s_2)),fail.
36
37 :- table s/1.
38 s(_).
0 caught_p
1 caught_r
2 caught_s_1
3 caught_s_2
4 uwoc_caught_r
5 uwoc_caught_s_2
0
1 /* Test of handling large subgoals and answers */
2
3 test:- test_large_ground_subgoal,writeln(test_large_ground_subgoal),fail.
4 test:- test_large_ground_answer,writeln(test_large_ground_answer),fail.
5 test:- test_subgoal_abstraction(50000,_L),writeln(test_subgoal_abstraction),fail.
6 test:- test_answer_abstraction(50000,_L),writeln(test_answer_abstraction),fail.
7 test:- test_subgoal_answer_abstraction(50000,_L,_M),writeln(test_subgoal_answer_abstraction),fail.
8 test:- catch(test_var_limit(1900,_L2),_E,writeln(subgoal_var_limit_one_caught)),fail. %new
9 test:- catch(test_var_limit(100000,_L2),_E,writeln(subgoal_var_limit_two_tested)),fail.
10 test:- catch(a_var(100000,_L2),_E,writeln(answer_var_limit_tested)),fail.
11 test.
12
13 %---------
14
15 test_large_ground_subgoal:- makelist(50000,X),s(X).
16 :-table s/1.
17 s(_X).
18
19 %---------
20
21 test_large_ground_answer:- a(50000,_X).
22 :- table a/2.
23 a(N,X):- makelist(N,X).
24
25 %---------
26
27 :-table sa/1 as subgoal_abstract(10).
28 sa(_X).
29
30 test_subgoal_abstraction(N,L):-
31 abolish_all_tables,
32 set_prolog_flag(max_table_subgoal_size_action,abstract),
33 makelist(N,L),
34 sa(L).
35
36 :- table r/2.
37 r(N,L):- makelist(N,L).
38
39 %---------
40
41 test_answer_abstraction(N,L):-
42 abolish_all_tables,
43 set_prolog_flag(max_table_answer_size,10),
44 set_prolog_flag(max_table_answer_size_action,bounded_rationality),
45 r(N,L).
46
47 %---------
48
49 :- table b/3 as subgoal_abstract(10).
50 b(N,_L,M):- makelist(N,M).
51
52 test_subgoal_answer_abstraction(N,L,M):-
53 abolish_all_tables,
54 set_prolog_flag(max_table_subgoal_size_action,abstract),
55 set_prolog_flag(max_table_answer_size,10),
56 set_prolog_flag(max_table_answer_size_action,bounded_rationality),
57 makelist(N,L),
58 b(N,L,M).
59
60 test_var_limit(N):-
61 set_prolog_flag(max_table_subgoal_var_num,N),
62 set_prolog_flag(max_table_answer_var_num,N),
63 test_var_limit(N,_L2).
64
65 test_var_limit(N,L2):-
66 set_prolog_flag(max_table_subgoal_size,10000000),
67 set_prolog_flag(max_table_answer_size,10000000),
68 abolish_all_tables,
69 makevarlist(N,L1),
70 s(L1),
71 makevarlist(N,L2),
72 s(L2),
73 L1 = L2,
74 writeln(test_var_limit_1_succeeded).
75
76 %---------
77
78 test_large_nonground_answer:- a(50000,_X).
79 :- table a_var/2.
80 a_var(N,X):-
81 makevarlist(N,X),
82 writeln(test_a_var_succeeded).
83
84 %---------
85
86 makelist(0,[]):- !.
87 makelist(N,[N|T]):- N1 is N - 1, makelist(N1,T).
88
89 makevarlist(0,[]):- !.
90 makevarlist(N,[_N|T]):- N1 is N - 1, makevarlist(N1,T).
91
0 test_large_ground_subgoal
1 test_large_ground_answer
2 test_subgoal_abstraction
3 test_answer_abstraction
4 test_subgoal_answer_abstraction
5 test_var_limit_1_succeeded
6 test_var_limit_1_succeeded
7 test_a_var_succeeded
22 get_residual(p(3,3),[])
33 get_residual(p(4,4),[])
44 get_residual(p(5,5),[])
5 get_residual(p(A,B),[restraint_number_of_answers])
5 get_residual(p(A,B),[answer_count_restraint])
0
1 :- table p/1.
2 p(_X).
3
4 :- table q/1 as subgoal_abstract(2).
5 q(_X).
6
7 % error -- "deep" terms
8 test:- set_prolog_flag(unify_with_occurs_check,off),fail.
9 test:- set_prolog_flag(max_table_subgoal_size_action,error),set_prolog_flag(max_table_subgoal_size,2),fail.
10 test:- catch(p(f(f(f(1)))),_E,(writeln(error(e1)),fail)),writeln(success(e1)),fail.
11 test:- abolish_table_pred(p/1),fail.
12 test:- catch(p(f(f(f(1)))),_E,(writeln(error(e2)),fail)),writeln(success(e2)),fail.
13 test:- abolish_table_call(p(f(f(f(1))))),fail.
14 test:- abolish_all_tables,fail.
15 %
16 % error -- cyclic terms
17 test:- X = f(X),catch(p(X),_E,(writeln(error(ce1)),fail)),writeln(success(ce1)),fail.
18 test:- abolish_table_pred(p/1),fail.
19 test:- X = f(X),catch(p(X),_E,(writeln(error(ce2)),fail)),writeln(success(ce2)),fail.
20 test:- X = f(X),catch(abolish_table_call(p(X)),_E,(writeln(error(ce3)),fail)),fail.
21 test:- abolish_all_tables,fail.
22 %
23 % error -- "deep" terms / tnot
24 test:- catch(tnot(p(f(f(f(1))))),_E,(writeln(error(e3)),fail)),writeln(success(e3)),fail.
25 test:- abolish_table_pred(p/1),fail.
26 test:- catch(tnot(p(f(f(f(1))))),_E,(writeln(error(e4)),fail)),writeln(success(e4)),fail.
27 test:- abolish_table_call(p(f(f(f(1))))),fail.
28 test:- abolish_all_tables,fail.
29 %
30 % error -- cyclic terms / tnot
31 test:- X = f(X),catch(tnot(p(X)),_E,(writeln(error(ce4)),fail)),writeln(success(ce4)),fail.
32 test:- abolish_table_pred(p/1),fail.
33 test:- X = f(X),catch(tnot(p(X)),_E,(writeln(error(ce5)),fail)),writeln(success(ce5)),fail.
34 test:- X = f(X),catch(abolish_table_call(p(X)),_E,(writeln(error(ce6)),fail)),fail.
35 test:- abolish_all_tables,fail.
36 %
37 %% abstraction -- "deep" terms
38 test:- set_prolog_flag(max_table_subgoal_size_action,abstract),fail.
39 test:- catch(q(f(f(f(1)))),_E,(writeln(error(a1)),fail)),writeln(success(a1)),fail.
40 test:- abolish_table_pred(q/1),fail.
41 test:- catch(q(f(f(f(1)))),_E,(writeln(error(a2)),fail)),writeln(success(a2)),fail.
42 test:- abolish_table_call(q(f(f(f(1))))),fail.
43 test:- abolish_all_tables,fail.
44 %
45 % abstraction -- cyclic terms
46 test:- X = f(X),catch(q(X),_E,(writeln(error(ca1)),fail)),writeln(success(ca1)),fail.
47 test:- abolish_table_pred(q/1),fail.
48 test:- X = f(X),catch(q(X),_E,(writeln(error(ca2)),fail)),writeln(success(ca2)),fail.
49 test:- X = f(X),catch(abolish_table_call(q(X)),_E,(writeln(error(cae3)),fail)),fail.
50 test:- abolish_all_tables,fail.
51 %
52 % abstraction -- "deep" terms / tnot
53 test:- catch(tnot(q(f(f(f(1))))),_E,(writeln(error(a3)),fail)),writeln(success(a3)),fail.
54 test:- abolish_table_pred(q/1),fail.
55 test:- catch(tnot(q(f(f(f(1))))),_E,(writeln(error(a4)),fail)),writeln(success(a4)),fail.
56 test:- abolish_table_call(q(f(f(f(1))))),fail.
57 test:- abolish_all_tables,fail.
58 %%
59 % abstraction -- cyclic terms / tnot
60 test:- X = f(X),catch(tnot(q(X)),_E,(writeln(error(ca4)),fail)),writeln(success(ca3)),fail.
61 test:- abolish_table_pred(q/1),fail.
62 test:- X = f(X),catch(tnot(q(X)),_E,(writeln(error(ca4)),fail)),writeln(success(ca4)),fail.
63 test:- X = f(X),catch(abolish_table_call(q(X)),_E,(writeln(error(cae4)),fail)),fail.
64 test:- abolish_all_tables,fail.
65 %
66 %TBD: floundering goals are not yet detected properly
67 %test:- catch(tnot(q(_X)),_E,(writeln(error(f1)),fail)),fail.
68 %%
69 test:- X = f(X),catch(tnot(X),_E,(writeln(error(c1)),fail)),fail.
70 %%
71 test:- set_prolog_flag(max_table_subgoal_size_action,error),fail.
72 test.
0 error(a3)
1 error(a4)
2 error(c1)
3 error(ca4)
4 error(ca4)
5 error(cae3)
6 error(cae4)
7 error(ce1)
8 error(ce2)
9 error(ce3)
10 error(ce4)
11 error(ce5)
12 error(ce6)
13 error(e1)
14 error(e2)
15 error(e3)
16 error(e4)
17 success(a1)
18 success(a2)
19 success(ca1)
20 success(ca2)
0
1 /*
2 Need to test out doubles for p3/p7
3 */
4
5 :- compiler_options([spec_off]).
6
7 %:- set_prolog_flag(max_table_subgoal_size_action,failure).
8 :- set_prolog_flag(max_table_subgoal_size_action,abstract).
9 :- set_prolog_flag(max_table_subgoal_size,2).
10 %:- import start_forest_view/1 from tables.
11 %?- start_forest_view(userout).
12
13 %--------------------
14 :- table p1/1.
15 p1(X):- Y = f(X),p1(Y).
16 p1(1).
17
18 %--------------------
19 :- table p11/1.
20 p11(X):- p11(f(X)).
21 p11(1).
22
23 %--------------------
24 :- table p12/1.
25 p12(X):- Y = [X],
26 % writeln(calling(p12(Y))),
27 p12(Y).
28 p12(1).
29
30 %--------------------
31 :- table p2/1.
32 p2(1).
33 p2(X):- Y = f(X),p2(Y).
34
35 %--------------------
36 :- table p21/1.
37 p21(1).
38 p21(X):- p21(f(X)).
39
40 %--------------------
41 :- table p22/1.
42 p22(1).
43 p22(X):- p22([X]).
44
45 %--------------------
46 :- table p3/1.
47 p3(X):- %writeln(entering_clause(X)),
48 p3(f(X)).
49 % writeln(succeeded_clause(X)).
50 p3(X):- %writeln(entering_fact(X)),
51 X = f(1).
52 %writeln(succeeded_fact(X)).
53 %p3(X):- X = f(1).
54
55 %p3(f(f(f(f(f(f(1))))))).
56 %p3(f(f(f(f(f(1)))))).
57 %--------------------
58 :- table p31/1.
59 p31(X):-
60 %writeln(calling([X])),
61 p31([X]).
62 p31([1]).
63
64 %--------------------
65
66 :- table p4/1.
67 %p4(f(f(f(f(f(f(1))))))).
68 p4(f(1)).
69 p4(X):-
70 %writeln(calling(p4(f(X)))),
71 p4(f(X)).
72
73 %--------------------
74
75 :- table p41/1.
76 p41([1]).
77 p41(X):-
78 %writeln(calling(p41([X]))),
79 p41([X]).
80
81 %--------------------
82
83 :- table p5/1.
84 p5(f(g(f(1)))).
85 p5(f(g(f(2)))).
86
87 %--------------------
88
89 :- table p6/1.
90 p6(_X).
91 p6(X):- p6(f(X)).
92
93 %--------------------
94
95 :- table p7/1.
96 p7(X):- p7(f(X)).
97 p7(_X).
98
99 %--------------------
100
101 :- table d1/2.
102 d1(1,1).
103 d1(X,Y):- d1(f(X),f(Y)).
104
105 %--------------------
106
107 :- table d11/2.
108 d11(1,1).
109 d11(X,Y):- d11([X],[Y]).
110
111 %--------------------
112
113 :- table d2/2.
114 d2(X,Y):- d2(f(X),f(Y)).
115 d2(1,1).
116
117 %--------------------
118
119 :- table p8/1.
120 p8(X):- p8(f(X)).
121 p8(f(f(f(1)))).
122 p8(f(f(g(2)))).
123 p8(f(f(f(3)))).
124 p8(f(f(g(4)))).
125
126 %--------------------
127
128 %--------------------
129 :- table n1/1.
130
131 n1(X):- tnot(n1(f(X))).
132 n1(1).
133
134 %--------------------
135
136 test:- setof(X,p1(X),Xs),
137 (Xs == [1] -> writeln('>>>>>succeeded(p1)')
138 ; writeln('>>>>>failed(p1)') ),fail.
139 test:- setof(X,p11(X),Xs),
140 (Xs == [1] -> writeln('>>>>>succeeded(p11)')
141 ; writeln('>>>>>failed(p11)') ),fail.
142 test:- setof(X,p2(X),Xs),
143 (Xs == [1] -> writeln('>>>>>succeeded(p2)')
144 ; writeln('>>>>>failed(p2)') ),fail.
145 test:- setof(X,p21(X),Xs),
146 (Xs == [1] -> writeln('>>>>>succeeded(p21)')
147 ; writeln('>>>>>failed(p21)') ),fail.
148 test:- setof(X,p3(X),Xs),
149 (Xs == [1,f(1)] -> writeln('>>>>>succeeded(p3)')
150 ; writeln('>>>>>failed(p3)') ),fail.
151 test:- setof(X,p31(X),Xs),
152 (Xs == [1,[1]] -> writeln('>>>>>succeeded(p31)')
153 ; writeln('>>>>>failed(p31)') ),fail.
154 test:- setof(X,p4(X),Xs),
155 (Xs == [1,f(1)] -> writeln('>>>>>succeeded(p4)')
156 ; writeln('>>>>>failed(p4)') ),fail.
157 test:- setof(X,p41(X),Xs),
158 (Xs == [1,[1]] -> writeln('>>>>>succeeded(p41)')
159 ; writeln('>>>>>failed(p41)') ),fail.
160 test:- test5.
161 test:- test5a.
162 test:- test5b.
163 test:- test6.
164 test:- test7.
165 test:- testd1.
166 test:- testd11.
167 test.
168
169 test5:- abolish_all_tables,
170 setof(X,p5(f(g(f(X)))),Xs),
171 (Xs == [1,2] -> writeln('>>>>>succeeded(p5)')
172 ; writeln('>>>>>failed(p5)') ),fail.
173 test5a:- abolish_all_tables,
174 (p5(_),fail ; true),
175 setof(X,p5(f(g(f(X)))),Xs),
176 (Xs == [1,2] -> writeln('>>>>>succeeded(p5a)')
177 ; writeln('>>>>>failed(p5a)') ),fail.
178 test5b:- abolish_all_tables,
179 (p5(_),fail ; true),
180 findall(1,p5(f(g(f(3)))),Xs),
181 (Xs == [] -> writeln('>>>>>succeeded(p5b)')
182 ; writeln('>>>>>failed(p5b)') ),fail.
183
184 test6:- abolish_all_tables,
185 (p6(_),fail ; true),
186 findall(X,get_residual(p6(X),_Y),Xs),
187 (Xs = [_,f(_),f(f(_))] -> writeln('>>>>>succeeded(p6)')
188 ; writeln('>>>>>failed(p6)') ),fail.
189
190 test7:- abolish_all_tables,
191 (p7(_),fail ; true),
192 findall(X,get_residual(p7(X),_Y),Xs),
193 (Xs = [_,f(_),f(f(_))] -> writeln('>>>>>succeeded(p7)')
194 ; writeln('>>>>>failed(p7)') ),fail.
195
196 testd1:- abolish_all_tables,
197 setof([X,Y],d1(X,Y),Xs),
198 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d1)')
199 ; writeln('>>>>>failed(d1)') ),fail.
200 testd11:- abolish_all_tables,
201 setof([X,Y],d11(X,Y),Xs),
202 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d11)')
203 ; writeln('>>>>>failed(d11)') ),fail.
204
205 testd2:- abolish_all_tables,
206 setof([X,Y],d2(X,Y),Xs),
207 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d2)')
208 ; writeln('>>>>>failed(d2)') ),fail.
0
1 /*
2 Need to test out doubles for p3/p7
3 */
4
5 :- compiler_options([spec_off]).
6
7 :- set_prolog_flag(max_table_subgoal_size_action,abstract).
8 %:- set_prolog_flag(max_table_subgoal_depth,2).
9
10 %:- import start_forest_view/1 from tables.
11 %?- start_forest_view(userout).
12
13 %--------------------
14 :- table p1/1 as subgoal_abstract(2).
15 p1(X):- Y = f(X),p1(Y).
16 p1(1).
17
18 %--------------------
19 :- table p11/1 as subgoal_abstract(2).
20 p11(X):- p11(f(X)).
21 p11(1).
22
23 %--------------------
24 :- table p12/1 as subgoal_abstract(2).
25 p12(X):- Y = [X],
26 % writeln(calling(p12(Y))),
27 p12(Y).
28 p12(1).
29
30 %--------------------
31 :- table p2/1 as subgoal_abstract(2).
32 p2(1).
33 p2(X):- Y = f(X),p2(Y).
34
35 %--------------------
36 :- table p21/1 as subgoal_abstract(2).
37 p21(1).
38 p21(X):- p21(f(X)).
39
40 %--------------------
41 :- table p22/1 as subgoal_abstract(2).
42 p22(1).
43 p22(X):- p22([X]).
44
45 %--------------------
46 :- table p3/1 as subgoal_abstract(2).
47 p3(X):- %writeln(entering_clause(X)),
48 p3(f(X)).
49 % writeln(succeeded_clause(X)).
50 p3(X):- %writeln(entering_fact(X)),
51 X = f(1).
52 %writeln(succeeded_fact(X)).
53 %p3(X):- X = f(1).
54
55 %p3(f(f(f(f(f(f(1))))))).
56 %p3(f(f(f(f(f(1)))))).
57 %--------------------
58 :- table p31/1 as subgoal_abstract(2).
59 p31(X):-
60 %writeln(calling([X])),
61 p31([X]).
62 p31([1]).
63
64 %--------------------
65
66 :- table p4/1 as subgoal_abstract(2).
67 %p4(f(f(f(f(f(f(1))))))).
68 p4(f(1)).
69 p4(X):-
70 %writeln(calling(p4(f(X)))),
71 p4(f(X)).
72
73 %--------------------
74
75 :- table p41/1 as subgoal_abstract(2).
76 p41([1]).
77 p41(X):-
78 %writeln(calling(p41([X]))),
79 p41([X]).
80
81 %--------------------
82
83 :- table p5/1 as subgoal_abstract(2).
84 p5(f(g(f(1)))).
85 p5(f(g(f(2)))).
86
87 %--------------------
88
89 :- table p6/1 as subgoal_abstract(2).
90 p6(_X).
91 p6(X):- p6(f(X)).
92
93 %--------------------
94
95 :- table p7/1 as subgoal_abstract(2).
96 p7(X):- p7(f(X)).
97 p7(_X).
98
99 %--------------------
100
101 :- table d1/2 as subgoal_abstract(2).
102 d1(1,1).
103 d1(X,Y):- d1(f(X),f(Y)).
104
105 %--------------------
106
107 :- table d11/2 as subgoal_abstract(2).
108 d11(1,1).
109 d11(X,Y):- d11([X],[Y]).
110
111 %--------------------
112
113 :- table d2/2 as subgoal_abstract(2).
114 d2(X,Y):- d2(f(X),f(Y)).
115 d2(1,1).
116
117 %--------------------
118
119 :- table p8/1 as subgoal_abstract(2).
120 p8(X):- p8(f(X)).
121 p8(f(f(f(1)))).
122 p8(f(f(g(2)))).
123 p8(f(f(f(3)))).
124 p8(f(f(g(4)))).
125
126 %--------------------
127
128 %--------------------
129 :- table n1/1 as subgoal_abstract(2).
130
131 n1(X):- tnot(n1(f(X))).
132 n1(1).
133
134 %--------------------
135
136 test:- setof(X,p1(X),Xs),
137 (Xs == [1] -> writeln('>>>>>succeeded(p1)')
138 ; writeln('>>>>>failed(p1)') ),fail.
139 test:- setof(X,p11(X),Xs),
140 (Xs == [1] -> writeln('>>>>>succeeded(p11)')
141 ; writeln('>>>>>failed(p11)') ),fail.
142 test:- setof(X,p2(X),Xs),
143 (Xs == [1] -> writeln('>>>>>succeeded(p2)')
144 ; writeln('>>>>>failed(p2)') ),fail.
145 test:- setof(X,p21(X),Xs),
146 (Xs == [1] -> writeln('>>>>>succeeded(p21)')
147 ; writeln('>>>>>failed(p21)') ),fail.
148 test:- setof(X,p3(X),Xs),
149 (Xs == [1,f(1)] -> writeln('>>>>>succeeded(p3)')
150 ; writeln('>>>>>failed(p3)') ),fail.
151 test:- setof(X,p31(X),Xs),
152 (Xs == [1,[1]] -> writeln('>>>>>succeeded(p31)')
153 ; writeln('>>>>>failed(p31)') ),fail.
154 test:- setof(X,p4(X),Xs),
155 (Xs == [1,f(1)] -> writeln('>>>>>succeeded(p4)')
156 ; writeln('>>>>>failed(p4)') ),fail.
157 test:- setof(X,p41(X),Xs),
158 (Xs == [1,[1]] -> writeln('>>>>>succeeded(p41)')
159 ; writeln('>>>>>failed(p41)') ),fail.
160 test:- test5.
161 test:- test5a.
162 test:- test5b.
163 test:- test6.
164 test:- test7.
165 test:- testd1.
166 test:- testd11.
167 test.
168
169 test5:- abolish_all_tables,
170 setof(X,p5(f(g(f(X)))),Xs),
171 (Xs == [1,2] -> writeln('>>>>>succeeded(p5)')
172 ; writeln('>>>>>failed(p5)') ),fail.
173 test5a:- abolish_all_tables,
174 (p5(_),fail ; true),
175 setof(X,p5(f(g(f(X)))),Xs),
176 (Xs == [1,2] -> writeln('>>>>>succeeded(p5a)')
177 ; writeln('>>>>>failed(p5a)') ),fail.
178 test5b:- abolish_all_tables,
179 (p5(_),fail ; true),
180 findall(1,p5(f(g(f(3)))),Xs),
181 (Xs == [] -> writeln('>>>>>succeeded(p5b)')
182 ; writeln('>>>>>failed(p5b)') ),fail.
183
184 test6:- abolish_all_tables,
185 (p6(_),fail ; true),
186 findall(X,get_residual(p6(X),_Y),Xs),
187 (Xs = [_,f(_),f(f(_))] -> writeln('>>>>>succeeded(p6)')
188 ; writeln('>>>>>failed(p6)') ),fail.
189
190 test7:- abolish_all_tables,
191 (p7(_),fail ; true),
192 findall(X,get_residual(p7(X),_Y),Xs),
193 (Xs = [_,f(_),f(f(_))] -> writeln('>>>>>succeeded(p7)')
194 ; writeln('>>>>>failed(p7)') ),fail.
195
196 testd1:- abolish_all_tables,
197 setof([X,Y],d1(X,Y),Xs),
198 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d1)')
199 ; writeln('>>>>>failed(d1)') ),fail.
200 testd11:- abolish_all_tables,
201 setof([X,Y],d11(X,Y),Xs),
202 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d11)')
203 ; writeln('>>>>>failed(d11)') ),fail.
204
205 testd2:- abolish_all_tables,
206 setof([X,Y],d2(X,Y),Xs),
207 (Xs = [[1,1]] -> writeln('>>>>>succeeded(d2)')
208 ; writeln('>>>>>failed(d2)') ),fail.
0 >>>>>succeeded(d1)
1 >>>>>succeeded(d11)
2 >>>>>succeeded(p1)
3 >>>>>succeeded(p11)
4 >>>>>succeeded(p2)
5 >>>>>succeeded(p21)
6 >>>>>succeeded(p3)
7 >>>>>succeeded(p31)
8 >>>>>succeeded(p4)
9 >>>>>succeeded(p41)
10 >>>>>succeeded(p5)
11 >>>>>succeeded(p5a)
12 >>>>>succeeded(p5b)
13 >>>>>succeeded(p6)
14 >>>>>succeeded(p7)
0 >>>>>succeeded(d1)
1 >>>>>succeeded(d11)
2 >>>>>succeeded(p1)
3 >>>>>succeeded(p11)
4 >>>>>succeeded(p2)
5 >>>>>succeeded(p21)
6 >>>>>succeeded(p3)
7 >>>>>succeeded(p31)
8 >>>>>succeeded(p4)
9 >>>>>succeeded(p41)
10 >>>>>succeeded(p5)
11 >>>>>succeeded(p5a)
12 >>>>>succeeded(p5b)
13 >>>>>succeeded(p6)
14 >>>>>succeeded(p7)
5252 )).
5353
5454 run_table_test(Test) :-
55 reset_table_defaults,
5556 xsb_test(table_tests,Test,xsb_test_tables:swi_test(Test)).
5657
5758 swi_test(M:_P) :-
5859 abolish_all_tables,
59 M:test.
60 M:test,
61 reset_table_defaults.
62
63 reset_table_defaults :-
64 set_prolog_flag(max_table_answer_size, infinite),
65 set_prolog_flag(max_table_answer_size_action, error),
66 set_prolog_flag(max_table_subgoal_size, infinite),
67 set_prolog_flag(max_table_subgoal_size_action, error),
68 set_prolog_flag(max_answers_for_subgoal, infinite),
69 set_prolog_flag(max_answers_for_subgoal_action, error).
70
6071
6172 :- begin_tests(xsb_test_tables, [sto(rational_trees)]).
6273
6778 table_test(abol_test3a). % atp gc diff preds
6879 table_test(abol_test3b). % atp gc diff preds + valid
6980 table_test(abol_test3c). % atp gc diff preds + valid + multiple gcs
70 table_test(atc_test).
7181 table_test(abolish_cascade). % cascading abolish for subgoals with gc etc.
7282 table_test(abolish_cascade_pred).
7383 table_test(abolish_cycle).
7484 table_test(abolish_dag).
7585 table_test(abolish_neg_cycle).
7686 table_test(abolish_neg_dag).
87 table_test(atc_test).
88 table_test(concomp).
89 table_test(expand).
90 table_test(ins).
91 table_test(large_arity_tables).
92 table_test(lrbug).
93 table_test(pps).
7794 table_test(pred_abolish_cycle).
7895 table_test(pred_abolish_dag).
7996 table_test(recursive_aboltest).
80 table_test(ins).
81 table_test(large_arity_tables).
82 table_test(concomp).
83 table_test(lrbug).
8497 table_test(tabbug1).
85 table_test(pps).
8698 table_test(test_3vwfs_1). % WFS with answer subsumption
87 %table_test(test_maxans_decl). % max_answers(Count) restraint
99 table_test(test_calldepth).
100 table_test(test_cyclic_tabling).% Cyclic term handling
101 table_test(test_large_tabled_terms).
102 table_test(test_maxans_decl). % max_answers(Count) restraint
103 table_test(test_negcycle).
104 table_test(test_tda). % subgoal_abstract restraint (abstract)
105 table_test(test_tda_i). % subgoal_abstract restraint (abstract)
88106
89107 :- end_tests(xsb_test_tables).
10861086 if ( d->canonical != d->name )
10871087 remove_string(d->canonical);
10881088 PL_free(d);
1089
1090 return;
10891091 }
10901092 }
10911093
17141714 setGITVersion();
17151715 }
17161716
1717 static int
1718 abi_version_dict(term_t dict)
1719 { GET_LD
1720 const atom_t keys[] = { ATOM_foreign_interface,
1721 ATOM_record,
1722 ATOM_qlf,
1723 ATOM_qlf_min_load,
1724 ATOM_vmi,
1725 ATOM_built_in };
1726 term_t values = PL_new_term_refs(6);
1727
1728 return ( PL_unify_integer(values+0, PL_version(PL_VERSION_FLI)) &&
1729 PL_unify_integer(values+1, PL_version(PL_VERSION_REC)) &&
1730 PL_unify_integer(values+2, PL_version(PL_VERSION_QLF)) &&
1731 PL_unify_integer(values+3, PL_version(PL_VERSION_QLF_LOAD)) &&
1732 PL_unify_integer(values+4, PL_version(PL_VERSION_VM)) &&
1733 PL_unify_integer(values+5, PL_version(PL_VERSION_BUILT_IN)) &&
1734
1735 PL_put_dict(dict, ATOM_abi, 6, keys, values) );
1736 }
1737
1738
1739 void
1740 setABIVersionPrologFlag(void)
1741 { GET_LD
1742 fid_t fid = PL_open_foreign_frame();
1743 term_t t = PL_new_term_ref();
1744
1745 if ( abi_version_dict(t) )
1746 setPrologFlag("abi_version", FF_READONLY|FT_TERM, t);
1747
1748 PL_discard_foreign_frame(fid);
1749 }
1750
17171751
17181752 void
17191753 cleanupPrologFlags(void)
7474 }
7575
7676
77 void
77 int
7878 PL_save_text(PL_chars_t *text, int flags)
7979 { if ( (flags & BUF_MALLOC) && text->storage != PL_CHARS_MALLOC )
8080 { size_t bl = bufsize_text(text, text->length+1);
8181 void *new = PL_malloc(bl);
8282
83 memcpy(new, text->text.t, bl);
84 text->text.t = new;
85 text->storage = PL_CHARS_MALLOC;
83 if ( new )
84 { memcpy(new, text->text.t, bl);
85 text->text.t = new;
86 text->storage = PL_CHARS_MALLOC;
87 } else
88 { return FALSE;
89 }
8690 } else if ( text->storage == PL_CHARS_LOCAL )
8791 { Buffer b = findBuffer(BUF_RING);
8892 size_t bl = bufsize_text(text, text->length+1);
101105
102106 text->storage = PL_CHARS_RING;
103107 }
108
109 return TRUE;
104110 }
105111
106112
119125 { memcpy(text->buf, text->text.t, bl);
120126 text->text.t = text->buf;
121127 text->storage = PL_CHARS_LOCAL;
128 } else if ( (flags&BUF_NORING) )
129 { return PL_save_text(text, BUF_MALLOC);
122130 } else
123131 { Buffer b = findBuffer(BUF_RING);
124132
344352
345353 Sclose(fd);
346354
347 return TRUE;
355 goto out;
348356 } else
349357 { Sclose(fd);
350358 if ( r != text->buf )
357365 { goto error;
358366 }
359367
360 succeed;
368 out:
369 if ( (flags&BUF_NORING) && text->storage == PL_CHARS_RING )
370 return PL_save_text(text, BUF_MALLOC);
371
372 return TRUE;
361373
362374 maybe_write:
363375 if ( (flags & (CVT_WRITE|CVT_WRITE_CANONICAL)) )
7878 int PL_concat_text(int n, PL_chars_t **text, PL_chars_t *result);
7979
8080 void PL_free_text(PL_chars_t *text);
81 void PL_save_text(PL_chars_t *text, int flags);
81 int PL_save_text(PL_chars_t *text, int flags);
8282
8383 COMMON(int) PL_get_text__LD(term_t l, PL_chars_t *text, int flags ARG_LD);
8484 COMMON(atom_t) textToAtom(PL_chars_t *text);
00 #define PLHOME "@PLHOME@"
11 #cmakedefine PLSHAREDHOME "@PLSHAREDHOME@"
2 #cmakedefine PLPKGNAME "@SWIPL_PKG_NAME@"
23 #define PLARCH "@PLARCH@"
34 #define C_CC "@C_CC@"
45 #define C_CXX "@C_CXX@"
35723572 return TRUE;
35733573 }
35743574
3575 if ( n1->value.f <= PLMAXINT && n1->value.f >= PLMININT )
3575 if ( n1->value.f <= (float)PLMAXINT && n1->value.f >= (float)PLMININT )
35763576 { if ( n1->value.f > 0 )
35773577 { r->value.i = (int64_t)(n1->value.f + 0.5);
35783578 if ( r->value.i < 0 ) /* Why can this happen? */
506506
507507 int
508508 saveWakeup(wakeup_state *state, int forceframe ARG_LD)
509 { Word h;
510
511 state->flags = 0;
509 { state->flags = 0;
512510 state->outofstack = LD->outofstack;
513511
514 if ( *(h=valTermRef(LD->attvar.head)) ||
512 if ( *valTermRef(LD->attvar.head) ||
515513 exception_term ||
516514 forceframe )
517515 { term_t s;
516 Word h;
518517
519518 if ( !(state->fid = PL_open_foreign_frame()) )
520519 return FALSE; /* no space! */
526525 exception_term = 0;
527526 }
528527
529 if ( *h )
528 if ( *(h=valTermRef(LD->attvar.head)) )
530529 { state->flags |= WAKEUP_STATE_WAKEUP;
531530 s = PL_new_term_refs(2);
532531
140140 }
141141
142142
143 static inline int
144 is_key(word w)
145 { return isAtom(w) || isTaggedInt(w);
146 }
147
148
149143 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
150144 dict_lookup_ptr() returns a pointer to the value for a given key
151145 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
198192 if ( count > 0 )
199193 { data++; /* skip to key */
200194 deRef2(data, n1);
201 if ( !is_key(*n1) )
195 if ( !is_dict_key(*n1) )
202196 return -1;
203197
204198 for(; count > 1; count--, data += 2, n1=n2)
205199 { deRef2(data+2, n2);
206 if ( !is_key(*n2) )
200 if ( !is_dict_key(*n2) )
207201 return -1;
208202 if ( *n1 < *n2 )
209203 continue;
590584 { Word p = valTermRef(t);
591585
592586 deRef(p);
593 if ( is_key(*p) )
587 if ( is_dict_key(*p) )
594588 { *np = *p;
595589 return TRUE;
596590 }
615609 { Word np, vp;
616610
617611 deRef2(&f->arguments[0], np);
618 if ( is_key(*np) )
612 if ( is_dict_key(*np) )
619613 { *name = *np;
620614 deRef2(&f->arguments[1], vp);
621615 *value = linkVal(vp);
11601154 return FALSE;
11611155
11621156 deRef(np);
1163 if ( is_key(*np) )
1157 if ( is_dict_key(*np) )
11641158 { Word vp;
11651159
11661160 if ( (vp=dict_lookup_ptr(dict, *np PASS_LD)) )
16511645 return FALSE;
16521646 goto retry;
16531647 }
1648 }
1649
1650 return FALSE;
1651 }
1652
1653
1654 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1655 Part of FLI
1656 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
1657
1658 int
1659 PL_get_dict_key(atom_t key, term_t dict, term_t value)
1660 { GET_LD
1661 word d;
1662 Word vp;
1663
1664 if ( !is_dict_key(key) )
1665 return -1;
1666 if ( !get_dict_ex(dict, &d, FALSE PASS_LD) )
1667 return FALSE;
1668 if ( (vp=dict_lookup_ptr(d, key PASS_LD)) )
1669 { *valTermRef(value) = linkVal(vp);
1670 return TRUE;
16541671 }
16551672
16561673 return FALSE;
6262 return ( fd->name == ATOM_dict && fd->arity%2 == 1 );
6363 }
6464
65 static inline int
66 is_dict_key(word w)
67 { return isAtom(w) || isTaggedInt(w);
68 }
69
6570 #endif /*PL_DICT_H_INCLUDED*/
203203 };
204204
205205
206 #define SIGNATURE_SEED (0x1a3be34a)
207
208 static unsigned int
209 predicate_signature(const Definition def)
210 { char str[256];
211
212 Ssprintf(str, "%s/%d/%d",
213 stringAtom(def->functor->name),
214 (int)def->functor->arity,
215 def->flags);
216
217 return MurmurHashAligned2(str, strlen(str), SIGNATURE_SEED);
218 }
219
220
206221 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
207222 The extensions chain is used to allow calling PL_register_extensions()
208223 *before* PL_initialise() to get foreign extensions in embedded systems
323338
324339 def->impl.foreign.function = f->function;
325340 createForeignSupervisor(def, f->function);
341
342 if ( !extensions_loaded )
343 GD->foreign.signature ^= predicate_signature(def);
326344 } else
327345 { assert(0);
328346 }
38453845
38463846
38473847 /*******************************
3848 * DICT *
3849 *******************************/
3850
3851 int
3852 PL_put_dict(term_t t, atom_t tag,
3853 size_t len, const atom_t *keys, term_t values)
3854 { GET_LD
3855 Word p, p0;
3856 size_t size = len*2+2;
3857
3858 if ( (p0=p=allocGlobal(size)) )
3859 { *p++ = dict_functor(len);
3860 if ( tag )
3861 { if ( isAtom(tag) )
3862 { *p++ = tag;
3863 } else
3864 { invalid:
3865 gTop -= size;
3866 return -1;
3867 }
3868 } else
3869 { setVar(*p++);
3870 }
3871
3872 for(; len-- > 0; keys++, values++)
3873 { *p++ = linkVal(valTermRef(values));
3874 if ( is_dict_key(*keys) )
3875 *p++ = *keys;
3876 else
3877 goto invalid;
3878 }
3879
3880 if ( dict_order(p0, TRUE PASS_LD) )
3881 { setHandle(t, consPtr(p0, TAG_COMPOUND|STG_GLOBAL));
3882 DEBUG(CHK_SECURE, checkStacks(NULL));
3883 return TRUE;
3884 }
3885
3886 gTop -= size;
3887 return -2;
3888 }
3889
3890 return FALSE;
3891 }
3892
3893
3894 /*******************************
38483895 * TYPE *
38493896 *******************************/
38503897
45904637
45914638 return FALSE;
45924639 }
4640
4641 #ifndef SIGABRT
4642 #define SIGABRT 6 /* exit 134 --> aborted */
4643 #endif
45934644
45944645 void
45954646 PL_abort_process(void)
52985349
52995350
53005351 /*******************************
5352 * VERSION *
5353 *******************************/
5354
5355 unsigned int
5356 PL_version(int which)
5357 { switch(which)
5358 { case PL_VERSION_SYSTEM: return PLVERSION;
5359 case PL_VERSION_FLI: return PL_FLI_VERSION;
5360 case PL_VERSION_REC: return PL_REC_VERSION;
5361 case PL_VERSION_QLF: return PL_QLF_VERSION;
5362 case PL_VERSION_QLF_LOAD: return PL_QLF_LOADVERSION;
5363 case PL_VERSION_VM: return VM_SIGNATURE;
5364 case PL_VERSION_BUILT_IN: return GD->foreign.signature;
5365 default: return 0;
5366 }
5367 }
5368
5369
5370 /*******************************
53015371 * INIT *
53025372 *******************************/
53035373
438438 COMMON(int) setBackQuotes(atom_t a, unsigned int *flagp);
439439 COMMON(int) setRationalSyntax(atom_t a, unsigned int *flagp);
440440 COMMON(void) initPrologFlags(void);
441 COMMON(void) setABIVersionPrologFlag(void);
441442 COMMON(void) cleanupPrologFlags(void);
442443
443444 /* pl-pro.c */
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 1997-2019, University of Amsterdam
5 Copyright (c) 1997-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
238238 InitialiseHandle initialise_tail;
239239 PL_dispatch_hook_t dispatch_events; /* PL_dispatch_hook() */
240240
241 unsigned int signature; /* Foreign predicate signature */
241242 int _loaded; /* system extensions are loaded */
242243 } foreign;
243244
10561056 cref = cref->next;
10571057 }
10581058 }
1059
1060 DEBUG(CHK_SECURE,
1061 { for(cref=clist->first_clause; cref; cref=cref->next)
1062 { assert(false(cref->value.clause, CL_ERASED));
1063 }
1064 });
10651059
10661060 clist->erased_clauses = 0; /* see (*) */
10671061 }
22 Author: Jan Wielemaker
33 E-mail: J.Wielemaker@vu.nl
44 WWW: http://www.swi-prolog.org
5 Copyright (c) 2012-2019, University of Amsterdam
5 Copyright (c) 2012-2020, University of Amsterdam
66 VU University Amsterdam
77 CWI, Amsterdam
88 All rights reserved.
115115
116116
117117 static const char *
118 optcmp(const char *av, const char *opt)
119 { for(; *av && *opt && *av != '='; av++, opt++)
120 { if ( *av == *opt ||
121 (*av == '-' && *opt == '_') ||
122 (*av == '_' && *opt == '-') )
123 continue;
124
125 return NULL;
126 }
127
128 if ( !*opt )
129 { if ( *av == '=' )
130 av++;
131 return av;
132 } else
133 { return NULL;
134 }
135 }
136
137
138 static const char *
118139 longopt(const char *opt, int argc, const char **argv)
119 { size_t optlen = strlen(opt);
120
121 for(; argc > 0; argc--, argv++)
140 { for(; argc > 0; argc--, argv++)
122141 { const char *a = argv[0];
142 const char *v;
123143
124144 if ( *a++ == '-' && *a++ == '-' )
125145 { if ( *a == EOS ) /* --: end of args */
126146 return NULL;
127 if ( strncmp(a, opt, optlen) == 0 && a[optlen] == '=' )
128 return &a[optlen+1];
147 if ( (v=optcmp(a, opt)) && *v )
148 return v;
129149 }
130150 }
131151
135155
136156 static const char *
137157 is_longopt(const char *optstring, const char *name)
138 { size_t len = strlen(name);
139
140 if ( strncmp(optstring, name, len) == 0 )
141 { if ( optstring[len] == '=' )
142 return &optstring[len+1];
143 if ( optstring[len] == EOS )
144 return "";
158 { const char *v;
159
160 if ( (v=optcmp(optstring, name)) )
161 { return *v ? v : "";
145162 }
146163
147164 return NULL;
148165 }
149166
167
168 static const char *
169 skip_wsep(const char *s)
170 { if ( *s == '-' || *s == '_' )
171 s++;
172 return s;
173 }
150174
151175 static int
152176 is_bool_opt(const char *opt, const char *name, int *val)
168192 }
169193
170194 return -1;
171 } else if ( strncmp(opt, "no-", 3) == 0 &&
172 (optval=is_longopt(opt+3,name)) )
173 { if ( *optval == EOS )
174 { *val = FALSE;
175 return TRUE;
176 }
177
178 return -1;
179195 } else if ( strncmp(opt, "no", 2) == 0 &&
180 (optval=is_longopt(opt+2,name)) )
196 (optval=is_longopt(skip_wsep(opt+2),name)) )
181197 { if ( *optval == EOS )
182198 { *val = FALSE;
183199 return TRUE;
11131129 "%s: Usage:\n",
11141130 " 1) %s [options] prolog-file ... [-- arg ...]\n",
11151131 " 2) %s [options] [-o executable] -c prolog-file ...\n",
1116 " 3) %s --help Display this message (also -h)\n",
1117 " 4) %s --version Display version information\n",
1118 " 4) %s --arch Display architecture\n",
1119 " 6) %s --dump-runtime-variables[=format]\n"
1132 " 3) %s --help Display this message (also -h)\n",
1133 " 4) %s --version Display version information\n",
1134 " 5) %s --abi-version Display ABI version key\n",
1135 " 6) %s --arch Display architecture\n",
1136 " 7) %s --dump-runtime-variables[=format]\n"
11201137 " Dump link info in sh(1) format\n",
11211138 "\n",
11221139 "Options:\n",
11371154 " --quiet[=bool] (-q) Do (not) suppress informational messages\n",
11381155 " --traditional Disable extensions of version 7\n",
11391156 " --home=DIR Use DIR as SWI-Prolog home\n",
1140 " --stack_limit=size[BKMG] Specify maximum size of Prolog stacks\n",
1141 " --table_space=size[BKMG] Specify maximum size of SLG tables\n",
1157 " --stack-limit=size[BKMG] Specify maximum size of Prolog stacks\n",
1158 " --table-space=size[BKMG] Specify maximum size of SLG tables\n",
11421159 #ifdef O_PLMT
1143 " --shared_table_space=size[BKMG] Maximum size of shared SLG tables\n",
1160 " --shared-table-space=size[BKMG] Maximum size of shared SLG tables\n",
11441161 #endif
11451162 " --pce[=bool] Make the xpce gui available\n",
11461163 " --pldoc[=port] Start PlDoc server [at port]\n",
11471164 #ifdef __WINDOWS__
1148 " --win_app Behave as Windows application\n",
1165 " --win-app Behave as Windows application\n",
11491166 #endif
11501167 #ifdef O_DEBUG
11511168 " -d topic,topic,... Enable C-source DEBUG channels\n",
11521169 #endif
11531170 "\n",
11541171 "Boolean options may be written as --name=bool, --name, --no-name ",
1155 "or --noname\n",
1172 "or --noname.\n",
1173 "Both '-' or '_' are accepted as word-separator for long options.\n",
11561174 NULL
11571175 };
11581176 const cline *lp = lines;
11971215 }
11981216
11991217
1218 #ifndef PLPKGNAME
1219 #define PLPKGNAME "swipl"
1220 #endif
1221
1222 static int
1223 abi_version(void)
1224 { setupProlog();
1225 Sprintf(PLPKGNAME "-abi-%d-%d-%08x-%08x\n",
1226 PL_FLI_VERSION,
1227 PL_QLF_LOADVERSION,
1228 GD->foreign.signature,
1229 VM_SIGNATURE);
1230
1231 return TRUE;
1232 }
1233
1234
12001235 static int
12011236 arch(void)
12021237 { Sprintf("%s\n", PLARCH);
12071242
12081243 static int
12091244 giveVersionInfo(const char *a)
1210 { if ( a[0] != '-' || a[1] != '-' )
1245 { const char *v;
1246
1247 if ( *a++ != '-' || *a++ != '-' )
12111248 return FALSE;
12121249
1213 if ( streq(a, "--help") )
1250 if ( (v=is_longopt(a, "help")) && !*v )
12141251 return usage();
1215 if ( streq(a, "--arch") )
1252 if ( (v=is_longopt(a, "arch")) && !*v )
12161253 return arch();
1217 if ( streq(a, "--version") )
1254 if ( (v=is_longopt(a, "version")) && !*v )
12181255 return version();
1256 if ( (v=is_longopt(a, "abi_version")) && !*v )
1257 return abi_version();
12191258
12201259 return FALSE;
12211260 }
600600
601601 mark.term = f;
602602 mark.fdef = f->definition;
603 pushSegStack(&LD->cycle.lstack, mark, cycle_mark);
603 if ( !pushSegStack(&LD->cycle.lstack, mark, cycle_mark) )
604 return FALSE;
604605 f->definition = (functor_t)consUInt(info->size);
605606 /* overflow test (should not be possible) */
606607 DEBUG(CHK_SECURE, assert(valUInt(f->definition) == (uintptr_t)info->size));
614615 Sdprintf("Added %s/%d\n",
615616 stringAtom(valueFunctor(functor)->name),
616617 arityFunctor(functor)));
617 pushWorkAgenda(agenda, arity, f->arguments);
618 if ( !pushWorkAgenda(agenda, arity, f->arguments) )
619 return FALSE;
618620 continue;
619621 }
620622 default:
685687 size_t size;
686688 size_t rsize = SIZERECORD(flags);
687689 term_agenda agenda;
690 int rc;
688691
689692 DEBUG(CHK_SECURE, checkData(valTermRef(t)));
690693
697700 info.lock = !(info.external || (flags&R_NOLOCK));
698701
699702 initTermAgenda(&agenda, 1, valTermRef(t));
700 compile_term_to_heap(&agenda, &info PASS_LD);
703 rc = compile_term_to_heap(&agenda, &info PASS_LD);
701704 clearTermAgenda(&agenda);
702705 restoreVars(&info);
703706 unvisit(PASS_LD1);
704707
705 size = rsize + sizeOfBuffer(&info.code);
706 if ( allocate )
707 record = (*allocate)(closure, size);
708 else
709 record = PL_malloc_atomic_unmanaged(size);
710
711 if ( record )
712 {
708 if ( rc )
709 { size = rsize + sizeOfBuffer(&info.code);
710 if ( allocate )
711 record = (*allocate)(closure, size);
712 else
713 record = PL_malloc_atomic_unmanaged(size);
714
715 if ( record )
716 {
713717 #ifdef REC_MAGIC
714 record->magic = REC_MAGIC;
718 record->magic = REC_MAGIC;
715719 #endif
716 record->gsize = (unsigned int)info.size; /* only 28-bit */
717 record->nvars = info.nvars;
718 record->size = (int)size;
719 record->flags = flags;
720 if ( flags & R_DUPLICATE )
721 { record->references = 1;
722 }
723 memcpy(addPointer(record, rsize), info.code.base, sizeOfBuffer(&info.code));
720 record->gsize = (unsigned int)info.size; /* only 28-bit */
721 record->nvars = info.nvars;
722 record->size = (int)size;
723 record->flags = flags;
724 if ( flags & R_DUPLICATE )
725 { record->references = 1;
726 }
727 memcpy(addPointer(record, rsize), info.code.base, sizeOfBuffer(&info.code));
728 }
729 } else
730 { record = NULL;
724731 }
725732 discardBuffer(&info.code);
726733
749756 #define REC_GROUND 0x10 /* Record is ground */
750757 #define REC_VMASK 0xe0 /* Version mask */
751758 #define REC_VSHIFT 5 /* shift for version mask */
752 #define REC_VERSION 0x03 /* Version id */
753759
754760 #define REC_SZMASK (REC_32|REC_64) /* SIZE_MASK */
755761
759765 #define REC_SZ REC_32
760766 #endif
761767
762 #define REC_HDR (REC_SZ|(REC_VERSION<<REC_VSHIFT))
768 #define REC_HDR (REC_SZ|(PL_REC_VERSION<<REC_VSHIFT))
763769 #define REC_COMPAT(m) (((m)&(REC_VMASK|REC_SZMASK)) == REC_HDR)
764770
765771 typedef struct record_data
18431849 if ( !b.version_map )
18441850 { Sdprintf("PL_recorded_external(): "
18451851 "Incompatible version (%d, current %d)\n",
1846 save_version, REC_VERSION);
1852 save_version, PL_REC_VERSION);
18471853 fail;
18481854 }
18491855 }
140140 #ifdef O_LOCALE
141141 initLocale();
142142 #endif
143 setABIVersionPrologFlag();
143144 GD->io_initialised = TRUE;
144145 GD->clauses.cgc_space_factor = 8;
145146 GD->clauses.cgc_stack_factor = 0.03;
281281 { PRED_LD
282282 PL_chars_t input, sep, pad;
283283 int rc = FALSE;
284 int flags = CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION;
284 int flags = CVT_ATOM|CVT_STRING|CVT_LIST|CVT_EXCEPTION|BUF_NORING;
285285
286286 input.storage = PL_CHARS_VIRGIN;
287287 sep.storage = PL_CHARS_VIRGIN;
137137 static int add_answer_count_restraint(void);
138138 static int add_radial_restraint(void);
139139 static int tbl_wl_tripwire(worklist *wl, atom_t action, atom_t wire);
140 static int tbl_pred_tripwire(Definition def, atom_t action, atom_t wire);
140141
141142 #define WL_IS_SPECIAL(wl) (((intptr_t)(wl)) & 0x1)
142143 #define WL_IS_WORKLIST(wl) ((wl) && !WL_IS_SPECIAL(wl))
21972198
21982199 for(; pp < ep; pp++)
21992200 { Word ap = *pp;
2200 *p++ = makeRefG(ap);
2201
2202 if ( isVar(*ap) )
2203 *p++ = makeRefG(ap);
2204 else
2205 *p++ = *ap;
22012206 }
22022207
22032208 if ( PL_is_variable(ret) )
22362241 #define AT_SHARED 0x0004 /* find a shared table */
22372242 #define AT_PRIVATE 0x0008 /* find a private table */
22382243 #define AT_NOCLAIM 0x0010 /* Do not claim ownership */
2244
2245
2246 #define AT_ABSTRACT 0x0020 /* subgoal_abstract(N) tabling */
22392247 #define AT_SCOPE_MASK (AT_SHARED|AT_PRIVATE)
2248
2249 static inline size_t
2250 pred_max_table_subgoal_size(const Definition def ARG_LD)
2251 { size_t limit;
2252
2253 limit = def->tabling ? def->tabling->subgoal_abstract : (size_t)-1;
2254 if ( limit == (size_t)-1 )
2255 limit = LD->tabling.restraint.max_table_subgoal_size;
2256
2257 return limit;
2258 }
2259
22402260
22412261 static trie *
22422262 get_answer_table(Definition def, term_t t, term_t ret, atom_t *clrefp,
22492269 tmp_buffer vars;
22502270 mark m;
22512271 int shared;
2272 size_abstract sa = {.from_depth = 2, .size = (size_t)-1};
22522273
22532274 #ifdef O_PLMT
22542275 if ( (flags & AT_SCOPE_MASK) )
22702291 shared = FALSE;
22712292 #endif
22722293
2294 if ( def ) /* otherwise we don't need it anyway */
2295 sa.size = pred_max_table_subgoal_size(def PASS_LD);
22732296 variants = variant_table(shared PASS_LD);
22742297 initBuffer(&vars);
22752298
22762299 retry:
22772300 Mark(m);
22782301 v = valTermRef(t);
2279 rc = trie_lookup(variants, NULL, &node, v, (flags&AT_CREATE), &vars PASS_LD);
2280
2281 if ( rc == TRUE )
2282 { if ( node->value )
2302 rc = trie_lookup_abstract(variants, NULL, &node, v, (flags&AT_CREATE),
2303 &sa, &vars PASS_LD);
2304
2305 if ( rc > 0 )
2306 { if ( rc == TRIE_ABSTRACTED )
2307 { atom_t action = LD->tabling.restraint.max_table_subgoal_size_action;
2308
2309 DEBUG(MSG_TABLING_RESTRAINT,
2310 Sdprintf("Trapped by subgoal size restraint\n"));
2311 if ( action == ATOM_abstract && !(flags&AT_ABSTRACT) )
2312 action = ATOM_error;
2313
2314 if ( action != ATOM_abstract )
2315 { if ( tbl_pred_tripwire(def, action, ATOM_max_table_subgoal_size) )
2316 { sa.size = (size_t)-1;
2317 emptyBuffer(&vars);
2318 goto retry;
2319 } else
2320 { discardBuffer(&vars);
2321 return NULL;
2322 }
2323 }
2324 }
2325
2326 if ( node->value )
22832327 { atrie = symbol_trie(node->value);
22842328 } else if ( (flags&AT_CREATE) )
22852329 { atom_t symb;
30453089 { if ( !wrapper )
30463090 wrapper = PL_new_term_ref();
30473091
3048 if ( unify_trie_term(atrie->data.variant, NULL, wrapper PASS_LD) )
3049 { int flags = true(atrie, TRIE_ISSHARED) ? AT_SHARED : AT_PRIVATE;
3050 return ( get_answer_table(NULL, wrapper, skeleton,
3092 if ( atrie->data.variant && wrapper &&
3093 unify_trie_term(atrie->data.variant, NULL, wrapper PASS_LD) )
3094 { worklist *wl = atrie->data.worklist;
3095 Definition def = WL_IS_WORKLIST(wl) ? wl->predicate : NULL;
3096 int flags = true(atrie, TRIE_ISSHARED) ? AT_SHARED : AT_PRIVATE;
3097 return ( get_answer_table(def, wrapper, skeleton,
30513098 NULL, flags|AT_NOCLAIM PASS_LD) != NULL);
30523099 }
30533100
32903337 { Word kp;
32913338 trie_node *node;
32923339 atom_t action;
3293 size_t abstract;
3340 size_abstract sa = {.from_depth = 2};
32943341 int rc;
32953342
32963343 #ifdef O_PLMT
33013348 if ( true(wl->table, TRIE_ISMAP) )
33023349 return wkl_mode_add_answer(wl, A2, A3 PASS_LD);
33033350
3304 abstract = pred_max_table_answer_size(wl->predicate PASS_LD);
3351 sa.size = pred_max_table_answer_size(wl->predicate PASS_LD);
33053352 rc = trie_lookup_abstract(wl->table, NULL, &node, kp,
3306 TRUE, abstract, NULL PASS_LD);
3353 TRUE, &sa, NULL PASS_LD);
33073354 if ( rc > 0 ) /* ok or abstracted */
33083355 { idg_node *idg;
33093356
42004247 */
42014248
42024249 static int
4203 tbl_variant_table(term_t closure, term_t variant, term_t Trie, term_t status, term_t ret,
4204 int flags ARG_LD)
4250 tbl_variant_table(term_t closure, term_t variant, term_t Trie,
4251 term_t abstract, term_t status, term_t ret, int flags ARG_LD)
42054252 { trie *atrie;
42064253 Definition def = NULL;
42074254 atom_t clref = 0;
42304277 PRED_IMPL("$tbl_variant_table", 5, tbl_variant_table, 0)
42314278 { PRED_LD
42324279
4233 return tbl_variant_table(A1, A2, A3, A4, A5, AT_CREATE PASS_LD);
4280 return tbl_variant_table(A1, A2, A3, 0, A4, A5, AT_CREATE PASS_LD);
4281 }
4282
4283
4284 /** '$tbl_abstract_table'(+Closure, :Wrapper, -Trie,
4285 -Abstract, -Status, -Skeleton)
4286
4287 Abstract is one of `0` or a generalization of Wrapper
4288 */
4289
4290 static
4291 PRED_IMPL("$tbl_abstract_table", 6, tbl_abstract_table, 0)
4292 { PRED_LD
4293
4294 return tbl_variant_table(A1, A2, A3, A4, A5, A6, AT_CREATE|AT_ABSTRACT PASS_LD);
42344295 }
42354296
42364297
42384299 PRED_IMPL("$tbl_moded_variant_table", 5, tbl_moded_variant_table, 0)
42394300 { PRED_LD
42404301
4241 return tbl_variant_table(A1, A2, A3, A4, A5, AT_CREATE|AT_MODED PASS_LD);
4302 return tbl_variant_table(A1, A2, A3, 0, A4, A5, AT_CREATE|AT_MODED PASS_LD);
42424303 }
42434304
42444305
64906551 PL_put_atom(av+0, wire) &&
64916552 PL_put_atom(av+1, action) &&
64926553 PL_put_atom(av+2, trie_symbol(wl->table)) &&
6554 PL_call_predicate(NULL, PL_Q_PASS_EXCEPTION, pred, av) );
6555 }
6556
6557
6558 static int
6559 tbl_pred_tripwire(Definition def, atom_t action, atom_t wire)
6560 { GET_LD
6561 static predicate_t pred = NULL;
6562 term_t av;
6563
6564 if ( !pred )
6565 pred = PL_predicate("tripwire", 3, "$tabling");
6566
6567 DEBUG(MSG_TABLING_RESTRAINT,
6568 Sdprintf("Calling %s\n", procedureName(pred)));
6569
6570 return ( (av = PL_new_term_refs(3)) &&
6571 PL_put_atom(av+0, wire) &&
6572 PL_put_atom(av+1, action) &&
6573 unify_definition(MODULE_user, av+2, def, 0, GP_QUALIFY) &&
64936574 PL_call_predicate(NULL, PL_Q_PASS_EXCEPTION, pred, av) );
64946575 }
64956576
68146895 PRED_DEF("$tbl_wkl_answer_trie", 2, tbl_wkl_answer_trie, 0)
68156896 PRED_DEF("$tbl_wkl_work", 6, tbl_wkl_work, NDET)
68166897 PRED_DEF("$tbl_variant_table", 5, tbl_variant_table, 0)
6898 PRED_DEF("$tbl_abstract_table", 6, tbl_abstract_table, 0)
68176899 PRED_DEF("$tbl_existing_variant_table", 5, tbl_existing_variant_table, 0)
68186900 PRED_DEF("$tbl_moded_variant_table", 5, tbl_moded_variant_table, 0)
68196901 #ifdef O_PLMT
18601860 ldnew->prolog_flag.table = copyHTable(ldold->prolog_flag.table);
18611861 PL_UNLOCK(L_PLFLAG);
18621862 }
1863 ldnew->tabling.restraint = ldold->tabling.restraint;
18631864 if ( !ldnew->thread.info->debug )
18641865 { ldnew->_debugstatus.tracing = FALSE;
18651866 ldnew->_debugstatus.debugging = DBG_OFF;
665665
666666 int
667667 trie_lookup_abstract(trie *trie, trie_node *node, trie_node **nodep,
668 Word k, int add, size_t abstract, TmpBuffer vars ARG_LD)
668 Word k, int add, size_abstract *abstract,
669 TmpBuffer vars ARG_LD)
669670 { term_agenda_P agenda;
670671 size_t var_number = 0;
671672 int rc = TRUE;
672673 size_t compounds = 0;
673674 tmp_buffer varb;
675 size_abstract sa = {.from_depth = 1, .size = (size_t)-1};
674676 size_t aleft = (size_t)-1;
675677
676678 TRIE_STAT_INC(trie, lookups);
677679 if ( !node )
678680 node = &trie->root;
681 if ( abstract )
682 sa = *abstract;
679683
680684 initTermAgenda_P(&agenda, 1, k);
681685 while( node )
695699 break; /* finished toplevel */
696700 }
697701
698 if ( compounds == 1 )
699 aleft = abstract;
702 if ( compounds == sa.from_depth )
703 aleft = sa.size;
700704
701705 w = *p;
702706 switch( tag(w) )
703707 { case TAG_VAR:
704708 if ( isVar(w) )
705 { add_var:
709 { word w2;
710
711 add_var:
706712 if ( var_number++ == 0 && !vars )
707713 { vars = &varb;
708714 initBuffer(vars);
709715 }
710716 addBuffer(vars, p, Word);
711 *p = w = ((((word)var_number))<<LMASK_BITS)|TAG_VAR;
717 w2 = ((((word)var_number))<<LMASK_BITS)|TAG_VAR;
718 if ( tag(w) == TAG_VAR )
719 *p = w2;
720 w = w2;
712721 }
713722 node = follow_node(trie, node, w, add PASS_LD);
714723 break;
761770
762771 for(; pp < ep; pp++)
763772 { Word vp = *pp;
764 setVar(*vp);
773 if ( tag(*vp) == TAG_VAR )
774 setVar(*vp);
765775 }
766776 if ( vars == &varb )
767777 discardBuffer(vars);
13011311
13021312 static int
13031313 trie_insert(term_t Trie, term_t Key, term_t Value, trie_node **nodep,
1304 int update, size_t abstract ARG_LD)
1314 int update, size_abstract *abstract ARG_LD)
13051315 { trie *trie;
13061316
13071317 if ( get_trie(Trie, &trie) )
13831393 PRED_IMPL("trie_insert", 3, trie_insert, 0)
13841394 { PRED_LD
13851395
1386 return trie_insert(A1, A2, A3, NULL, FALSE, (size_t)-1 PASS_LD);
1396 return trie_insert(A1, A2, A3, NULL, FALSE, NULL PASS_LD);
13871397 }
13881398
13891399 /**
13991409 PRED_IMPL("trie_insert", 2, trie_insert, 0)
14001410 { PRED_LD
14011411
1402 return trie_insert(A1, A2, 0, NULL, FALSE, (size_t)-1 PASS_LD);
1412 return trie_insert(A1, A2, 0, NULL, FALSE, NULL PASS_LD);
14031413 }
14041414
14051415
14121422 static
14131423 PRED_IMPL("$trie_insert_abstract", 3, trie_insert_abstract, 0)
14141424 { PRED_LD
1415 size_t size;
1416
1417 return ( PL_get_size_ex(A2, &size ) &&
1418 trie_insert(A1, A3, 0, NULL, FALSE, size PASS_LD) > 0 );
1425 size_abstract sa = {.from_depth = 1};
1426
1427 return ( PL_get_size_ex(A2, &sa.size ) &&
1428 trie_insert(A1, A3, 0, NULL, FALSE, &sa PASS_LD) > 0 );
14191429 }
14201430
14211431
14321442 PRED_IMPL("trie_update", 3, trie_update, 0)
14331443 { PRED_LD
14341444
1435 return trie_insert(A1, A2, A3, NULL, TRUE, (size_t)-1 PASS_LD);
1445 return trie_insert(A1, A2, A3, NULL, TRUE, NULL PASS_LD);
14361446 }
14371447
14381448
14521462 { PRED_LD
14531463 trie_node *node;
14541464
1455 return ( trie_insert(A1, A2, A3, &node, FALSE, (size_t)-1 PASS_LD) &&
1465 return ( trie_insert(A1, A2, A3, &node, FALSE, NULL PASS_LD) &&
14561466 PL_unify_pointer(A4, node) );
14571467 }
14581468
131131 struct idg_node *IDG; /* Node in the IDG graph */
132132 } data;
133133 } trie;
134
135 typedef struct size_abstract
136 { int from_depth; /* start below depth */
137 size_t size; /* limit each term to size */
138 } size_abstract;
134139
135140 #define acquire_trie(t) ATOMIC_INC(&(t)->references)
136141 #define release_trie(t) do { if ( ATOMIC_DEC(&(t)->references) == 0 ) \
168173 term_t term ARG_LD);
169174 COMMON(int) trie_lookup_abstract(trie *trie,
170175 trie_node *root, trie_node **nodep, Word k,
171 int add, size_t abstract,
176 int add, size_abstract *abstract,
172177 TmpBuffer vars ARG_LD);
173178 COMMON(int) trie_error(int rc, term_t culprit);
174179 COMMON(int) trie_trie_error(int rc, trie *trie);
195200 trie_lookup(trie *trie, trie_node *node, trie_node **nodep,
196201 Word k, int add, TmpBuffer vars ARG_LD)
197202 { return trie_lookup_abstract(trie, node, nodep, k, add,
198 (size_t)-1, vars PASS_LD);
203 NULL, vars PASS_LD);
199204 }
200205
201206 #endif /*_PL_TRIE_H*/
41364136 FR->clause = NULL;
41374137 goto exit_checking_wakeup;
41384138 case FALSE:
4139 FR->clause = NULL;
41394140 if ( exception_term )
41404141 THROW_EXCEPTION;
41414142 DEBUG(CHK_SECURE, assert(BFR->value.PC == PC));
174174 first. The last byte has its 0x80 mask set.
175175 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
176176
177 #define LOADVERSION 67 /* load all versions later >= X */
178 #define VERSION 67 /* save version number */
179177 #define QLFMAGICNUM 0x716c7374 /* "qlst" on little-endian machine */
180178
181179 #define XR_REF 0 /* reference to previous */
28222820 { IOSTREAM *fd = state->wicFd;
28232821
28242822 putMagic(saveMagic, fd);
2825 putInt64(VERSION, fd);
2823 putInt64(PL_QLF_VERSION, fd);
28262824 putInt64(VM_SIGNATURE, fd);
28272825 if ( systemDefaults.home )
28282826 putString(systemDefaults.home, STR_NOLEN, fd);
30443042 if ( cversion )
30453043 { int vm_signature;
30463044
3047 if ( !PL_unify_integer(cversion, VERSION) ||
3048 !PL_unify_integer(minload, LOADVERSION) ||
3045 if ( !PL_unify_integer(cversion, PL_QLF_VERSION) ||
3046 !PL_unify_integer(minload, PL_QLF_LOADVERSION) ||
30493047 !PL_unify_integer(csig, (int)VM_SIGNATURE) )
30503048 goto out;
30513049
31753173 initSourceMarks(state);
31763174
31773175 putMagic(qlfMagic, state->wicFd);
3178 putInt64(VERSION, state->wicFd);
3176 putInt64(PL_QLF_VERSION, state->wicFd);
31793177 putInt64(VM_SIGNATURE, state->wicFd);
31803178
31813179 putString(absname, STR_NOLEN, state->wicFd);
33243322
33253323 if ( !qlfVersion(state, magic, &lversion) )
33263324 return FALSE;
3327 if ( lversion < LOADVERSION )
3325 if ( lversion < PL_QLF_LOADVERSION )
33283326 return qlfError(state, "incompatible version (file: %d, Prolog: %d)",
3329 lversion, VERSION);
3327 lversion, PL_QLF_VERSION);
33303328 state->saved_version = lversion;
33313329
33323330 vm_signature = getInt(state->wicFd);
360360 }
361361
362362
363 /** '$wrapped_implementation'(:Goal, +Name, -Wrapped)
364 *
365 * Calling Wrapped calls the predicate referenced by Goal as seen
366 * from the wrapper Name.
367 */
368
369 static
370 PRED_IMPL("$wrapped_implementation", 3, wrapped_implementation,
371 PL_FA_TRANSPARENT)
372 { PRED_LD
373 Procedure proc;
374 atom_t wname;
375 Code codes;
376 term_t head = PL_new_term_ref();
377
378 if ( !PL_get_atom_ex(A2, &wname) ||
379 !get_procedure(A1, &proc, head, GP_RESOLVE) )
380 return FALSE;
381
382 if ( (codes = find_wrapper(proc->definition, wname)) )
383 { atom_t aref = codes[2];
384 size_t arity = proc->definition->functor->arity;
385
386 if ( arity > 0 )
387 { Word p;
388 term_t impl = PL_new_term_ref();
389
390 if ( (p=allocGlobal(1+arity)) )
391 { Word a = valTermRef(head);
392 size_t i;
393
394 deRef(a);
395 a = valueTerm(*a)->arguments;
396 p[0] = lookupFunctorDef(aref, arity);
397 for(i=0; i<arity; i++)
398 p[i+1] = linkVal(&a[i]);
399 *valTermRef(impl) = consPtr(p, TAG_COMPOUND|STG_GLOBAL);
400 return PL_unify(A3, impl);
401 }
402 } else
403 { return PL_unify_atom(A3, aref);
404 }
405 }
406
407 return FALSE;
408 }
409
410
363411 /**
364412 * unwrap_predicate(:Head, ?Name) is semidet.
365413 *
425473 * PUBLISH PREDICATES *
426474 *******************************/
427475
476 #define META PL_FA_TRANSPARENT
477
428478 BeginPredDefs(wrap)
429 PRED_DEF("$c_wrap_predicate", 5, c_wrap_predicate, PL_FA_TRANSPARENT)
430 PRED_DEF("unwrap_predicate", 2, uwrap_predicate, PL_FA_TRANSPARENT)
431 PRED_DEF("$wrapped_predicate", 2, wrapped_predicate, PL_FA_TRANSPARENT)
432 PRED_DEF("$closure_predicate", 2, closure_predicate, 0)
479 PRED_DEF("$c_wrap_predicate", 5, c_wrap_predicate, META)
480 PRED_DEF("unwrap_predicate", 2, uwrap_predicate, META)
481 PRED_DEF("$wrapped_predicate", 2, wrapped_predicate, META)
482 PRED_DEF("$wrapped_implementation", 3, wrapped_implementation, META)
483 PRED_DEF("$closure_predicate", 2, closure_predicate, 0)
433484 EndPredDefs
816816 PL_chars_t txt;
817817 int rc = TRUE;
818818
819 PL_get_text(t, &txt, CVT_STRING);
820 if ( txt.storage != PL_CHARS_LOCAL )
821 PL_save_text(&txt, BUF_MALLOC);
819 PL_get_text(t, &txt, CVT_STRING|BUF_NORING);
822820
823821 if ( true(options, PL_WRT_QUOTED) )
824822 { int quote;
6767 .B \-\-version
6868 Displays version and architecture information.
6969 .TP
70 .B \-\-abi_version
71 Displays ABI version key. This key indicates binary compatibility of
72 various interfaces.
73 .TP
7074 .B \-\-arch
7175 Prints the architecture identifier.
7276 .TP