-
I often tout that one of the major advantages of Prolog over other programming languages, even my beloved lisp, is the queryablity of code. After all, Prolog code is Prolog data! However, it strikes me that I don't actually know how to do this. I'm sure it's probably quite straight forward. I imagine it would be something like,
As you can see, my terminology gets a little shaky/procedural towards the end. Does anyone have any suggestions? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 17 replies
-
:- initialization(main).
main :-
slurp('example.pl', T),
maplist(assertkb, T).
assertkb(T) :-
T = (H :- B) -> (
once(list_sequence(L, B)),
assertz(kb(H, L))
); (
T = (':-'(B)) ->
true
; assertz(kb(T, []))
).
slurp(File, VTs) :-
open_call_close(collect_vars_terms(VTs), read, [type(text)], File).
collect_vars_terms(VTs, Stream) :-
findall([Vs,T], read_term_cp(Stream, T, [variable_names(Vs)]), VTs).
read_term_cp(Stream, Term, Options) :-
read_term(Stream, Term, Options), Term \== end_of_file -> true; !.
read_term_cp(Stream, Term, Options) :-
read_term_cp(Stream, Term, Options).
open_call_close(G_1, Method, Options, File) :-
setup_call_cleanup(
open(File, Method, Stream, Options),
call(G_1, Stream),
close(Stream)). Given you have file |
Beta Was this translation helpful? Give feedback.
-
In addition, clauses of public procedures can be inspected with :- dynamic(p/1). % dynamic implies public p(Xs) :- maplist(=(a), Xs), hello. p(_) :- there. Yielding: ?- clause(p(X), Body). Body = (maplist(=(a),X),hello) ; Body = there. |
Beta Was this translation helpful? Give feedback.
-
If you want to write the shortest possible predicate to read whole file as terms into memory, we can try to play code golf :) Here is my entry: :- use_module(library(lambda)).
slurp_in_one_clause(File, Terms) :-
setup_call_cleanup(
open(File, read, S, []),
(
L = \[A|T]^(copy_term(L,LP), read_term(S,A,[]), (A \= end_of_file -> call(LP, T); !, T = [])),
call(L, Terms)
),
close(S)
). Remark: I would never write such code in production ;) |
Beta Was this translation helpful? Give feedback.
For lack of a better answer, I'm going to go with this approach as the best current concise fully working answer for reading in a list of terms in a file in Scryer Prolog. Happy to relabel that if anyone has a different suggestion. Thanks to @hurufu for revealing the meat of the technique.