just started programming with prolog and I'm having a few issues. I wanna store the result on an operation , for example:
transformer(kilo,1000).
transformer(hecto,100).
transformer(deca,10).
transformer(unite,1).
transformer(deci,0.1).
transformer(centi,0.01).
transformer(milli,0.001).
transformerT(sec,1).
transformerT(min,60).
transformerT(h,3600).
plus(V1,U,V2,U,UniteType,R,U) :-
dif(UniteType,temps),R is V1+V2.
plus(V1,U1,V2,U2,UniteType,R,unite) :-
dif(UniteType,temps),
dif(U1,U2),
trans(U1,Res1),
trans(U2,Res2),
R is V1*Res1+V2*Res2.
I want to store the result of this operation to call it later (like the ANS or M Buttons in a calculator) in another operation. Is it Possible?
If you want the information to survive a program termination (i.e. a return to the Prolog REPL, aka. toplevel) you can use predicates asserta/2 and assertz/2.
See this section for SWI Prolog, should be similar for SICStus: Database
Alternatively you may want to keep the program "alive" and store information in a term that is passed between predicates. Association lists library(assoc) or, for SWI Prolog, built-in dicts, or simpler data structure like lists can be used for that.
Related
I have a small program that runs in python. Basically, it has a pretty simple loop: Query a Prolog program, do something with the result, change some state back in Prolog.
I have written a logical way (no mutations) to change a state in Prolog.
The queries use a state as their argument, and result in a new state. The question is, where do I store the new state?
I can pass it back and forth from Prolog to Python, but as the state grows large it might become problematic.
I can also store a global variable, but that seems like a bad solution.
This is the basic flow of my program:
some_query(OldState, NewState) :-
% do some stuff here
python code:
state = '[]'
while Not_Exit:
query = MyLogic(state) # state is not actually used here (python-wise), just to pass it to prolog
result = prologBridge.Query(query)
state = result["NewState"] # how do I change that in Prolog without passing the state back and forth?
EDIT:
The state contains a list of terms, and state changes revolve around adding and removing terms. For example. S1 = [T1, T2, T3] changes into S2 = [T2, T3, T4].
Possible solutions:
Store state or other facts in a file that you reconsult in Prolog.
Use data bases to persist state
Keep Prolog running as a separate process in the background, then current state should be available.
What is your choice ? what about functional programming ?
As long as each query runs in the same Prolog session (i.e., you don't start a new Prolog each time), you can use Prolog's built-in database. This is a store of "dynamic" Prolog clauses that can be modified at runtime.
You declare a dynamic predicate using a :- dynamic directive. You remove old facts using rectract or retractall and assert new ones using asserta or assertz. Querying a dynamic predicate is done by calling it as usual.
For example, you can declare your state like this:
:- dynamic mystate/1.
A predicate querying the state, computing the next one, and updating the database, looks like this:
query_and_update_state :-
mystate(OldState),
some_query(OldState, NewState),
write('new state: '),
write(NewState),
nl,
retractall(mystate(_)),
asserta(mystate(NewState)).
This assumes the existence of your some_query predicate. Some initial state must be set at the beginning as well. For example, if the state is just a counter:
init_state :-
retractall(mystate(_)),
asserta(mystate(0)).
some_query(Old, New) :-
succ(Old, New).
Running this interactively:
?- init_state.
true.
?- query_and_update_state.
new state: 1
true.
?- query_and_update_state.
new state: 2
true.
?- query_and_update_state.
new state: 3
true.
?- query_and_update_state.
new state: 4
true.
Your Python code would call init_state once and then call query_and_update_state repeatedly, presumably for some side effect. (It's not clear to me from your question.)
Caveat: If you're worried about the costs of copying the state, you might not be happy about this either. Asserting a state and querying it both involve making a complete deep copy of the data structure. Such a Prolog-Prolog copy might indeed be cheaper than a Prolog-Python copy. But depending on your Python-Prolog bridge, maybe it doesn't make a deep copy and could be cheaper? I don't know.
I am using SWI Prolog and am surprised to find no obvious way to do this in Prolog. What I'm after is something similar to clause/2 but allows uninstantiated first argument (and is specific to the clauses in a given file, ie I don't want the entire Prolog library!). Here is what I wrote to find all the clauses
clauseX(H,B) :-
current_predicate(P/Arity),
functor(H,P,Arity),
absolute_file_name('filname.pl', AbsFileName),
predicate_property(H, file(AbsFileName)),
clause(H,B).
Is there a more concise way of doing this?
OK, so I've been able to shorten it somewhat, the first two literals aren't required, this will return clauses in the file filename.pl
clauseX(H,B) :-
absolute_file_name('filname.pl', AbsFileName),
predicate_property(H, file(AbsFileName)),
clause(H,B).
However I am still concerned about the efficiency of this and whether it has to consult the file every time clauseX is called
Is it possible to use the prolog format predicate to print to file?
I have a table of data that I print to stdout using the format predicate, i.e.
print_table :-
print_table_header,
forall(range(1.0,10.0,0.1,N), print_row(N,L)).
%% print_row(L) :- take a list of the form, [a,b,c,d,e] and
%% print it to screen as a single row of tab separated float values (1DP)
print_row(N,L) :-
build_row(N,L),
format('~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~t~1f~10+ ~n', L).
print_table_header :-
format('~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~t~w~10+ ~n', ['N','N2','N3','N4','N5']).
would be nice to somehow reuse the code to print the same thing to file.
In addition to the other good answer (+1!), I would like to present a purer solution to such tasks.
The key idea is to make format/2 accessible within DCGs, and then to use a DCG to describe the output.
This is very easy, using the codes argument of format/3, provided by several Prolog implementations. All you need are the following short auxiliary definitions:
format_(Data, Args) --> call(format_dlist(Data, Args)).
format_dlist(Data, Args, Cs0, Cs) :- format(codes(Cs0,Cs), Data, Args).
The nonterminal call//1 calls its argument with two additional arguments that let you access the implicit DCG arguments, and this is used to describe additional codes via format/3.
Now, we can simply use the nonterminal format_//2 within DCGs.
For example, to describe a simple table:
table -->
row([a,b,c]),
row([d,e,f]).
row(Ls) --> format_("~t~w~10+~t~w~10+~t~w~10+~n", Ls).
Usage example and result:
?- phrase(table, Cs), format("~s", [Cs]).
a b c
d e f
Cs = [32, 32, 32, 32, 32, 32, 32, 32, 32|...].
Note that one last remaining format/2 is used to actually write the output to the screen.
However, everything else is free of side-effects and declaratively describes a table.
An important advantage of this method is that you can easily write test cases to see whether your tables are (still) correctly formatted. It is easy to reason about Prolog lists of codes (described with a DCG), but quite hard to reason about things that only appear on the terminal.
You can!
Consider the following extract of the SICStus Prolog documentation for format/[2,3]:
11.3.85 format/[2,3]
Synopsis
format(+Control, +Arguments)
format(+Stream, +Control, +Arguments)
Interprets the Arguments according to the Control string and prints the result on Stream.
The predicates format/[2,3] are widely supported across Prolog implementations.
However, as of right now, these predicates are not part of ISO Prolog.
I would write the output 'routines' with an additional parameter, a Stream, and then I would pass user while testing or printing to screen. See ISO predicates open/3, close/1 etc for stream handling...
Note that IO it's among the least 'declarative' areas of the language, because, for efficiency, an approach based on side effects is required...
SWI-Prolog has a builtin with_output_to, that would allows to reuse your existing code without adding a parameter. But since you tagged iso-prolog your question, you should really add the Stream parameter...
I am very new to Prolog and trying to learn.
For my program, I would like to have the user provide pairs of strings which are "types of".
For example, user provides at command line the strings "john" and "man". These atoms would be made to be equal, i.e. john(man).
At next prompt, then user provides "man" and "tall", again program asserts these are valid, man(tall).
Then the user could query the program and ask "Is john tall?". Or in Prolog: john(tall) becomes true by transitive property.
I have been able to parse the strings from the user's input and assign them to variables Subject and Object.
I tried a clause (where Subject and Object are different strings):
attribute(Subject, Object) :-
assert(term_to_atom(_ , Subject),
term_to_atom(_ , Object)).
I want to assert the facts that Subject and Object are valid pair. If the user asserts it, then they belong to together. How do I force this equality of the pairs?
What's the best way to go about this?
Questions of this sort have been asked a lot recently (I guess your professors all share notes or something) so a browse through recent history might have been productive for you. This one comes to mind, for instance.
Your code is pretty wide of the mark. This is what you're trying to do:
attribute(Subject, Object) :-
Fact =.. [Object, Subject],
assertz(Fact).
Using it works like this:
?- attribute(man, tall).
true.
?- tall(X).
X = man.
So, here's what you should notice about this code:
We're using =../2, the "univ" operator, to build structures from lists. This is the only way to create a fact from some atoms.
I've swapped subject and object, because doing it the other way is almost certainly not what you want.
The predicate you want is assertz/1 or asserta/1, not assert/2. The a and z on the end just tells Prolog whether you want the fact at the beginning or end of the database.
Based on looking at your code, I think you have a lot of baggage you need to shed to become productive with Prolog.
Prolog predicates do not return values. So assert(term_to_atom(... wasn't even on the right track, because you seemed to think that term_to_atom would "return" a value and it would get substituted into the assert call like in a functional or imperative language. Prolog just plain works completely differently from that.
I'm not sure why you have an empty variable in your term_to_atom predicates. I think you did that to satisfy the predicate's arity, but this predicate is pretty useless unless you have one ground term and one variable.
There is an assert/2, but it doesn't do what you want. It should be clear why assert normally only takes one argument.
Prolog facts should look like property(subject...). It is not easy to construct facts and then query them, which is what you'd have to do using man(tall). What you want to say is that there is a property, being tall, and man satisfies it.
I would strongly recommend you back up and go through some basic Prolog tutorials at this point. If you try to press forward you're only going to get more lost.
Edit: In response to your comment, I'm not sure how general you want to go. In the basic case where you're dealing with a 4-item list with [is,a] in the middle, this is sufficient:
build_fact([Subject,is,a,Object], is_a(Subject, Object)).
If you want to isolate the first and last and create the fact, you have to use univ again:
build_fact([Subject|Rest], Fact) :-
append(PredicateAtoms, [Object], Rest),
atomic_list_concat(PredicateAtoms, '_', Predicate),
Fact =.. [Predicate, Subject, Object].
Not sure if you want to live with the articles ("a", "the") that will wind up on the end though:
?- build_fact([john,could,be,a,man], Fact).
Fact = could_be_a(john, man)
Don't do variable fact heads. Prolog works best when the set of term names is fixed. Instead, make a generic place for storing properties using predefined, static term name, e.g.:
is_a(john, man).
property(man, tall).
property(john, thin).
(think SQL tables in a normal form). Then you can use simple assertz/1 to update the database:
add_property(X, Y) :- assertz(property(X, Y)).
How do I define a rule that the user cannot query?
I only want the program itself to call this rule through another rule.
Ex:
rule1():- rule2().
rule2():- 1<5.
?-rule1().
true
?-rule2().
(I don't know what the answer will be, I just want this query to fail!)
Use a Logtalk object to encapsulate your predicates. Only the predicates that you declare public can be called (from outside the object). Prolog modules don't prevent calling any predicate as using explcit qualification bypasses the list of explicitly exported predicates.
A simple example:
:- object(rules).
:- public(rule1/1).
rule1(X) :-
rule2(X).
rule2(X) :-
X < 5.
:- end_object.
After compiling and loading the object above:
?- rules::rule1(3).
true.
?- rules::rule2(3).
error(existence_error(predicate_declaration,rule2(3)),rules::rule2(3),user)
If you edit the object code and explicitly declare rule2/1 as private you would get instead the error:
?- rules::rule2(3).
error(permission_error(access,private_predicate,rule2(3)),rules::rule2(3),user)
More information and plenty of examples at http://logtalk.org/
First, some notes:
I think you mean "predicate" instead of "rule". A predicate is a name/k thing such as help/0 (and help/1 is another) and can have multiple clauses, among them facts and rules, e.g. length([], 0). (a fact) and length([H|T], L) :- ... . (a rule) are two clauses of one predicate length/2.
Do not use empty parenthesis for predicates with no arguments – in SWI-Prolog at least, this will not work at all. Just use predicate2 instead of predicate2() in all places.
If you try to call an undefined predicate, SWI-Prolog will say ERROR: toplevel: Undefined procedure: predicate2/0 (DWIM could not correct goal) and Sicstus-Prolog will say {EXISTENCE ERROR: predicate2: procedure user:predicate2/0 does not exist}
Now, to the answer. Two ideas come to my mind.
(1) This is a hack, but you could assert the predicate(s) every time you need them and retract them immediately afterwards:
predicate1 :-
assert(predicate2), predicate2, retractall(predicate2).
If you want a body and arguments for predicate2, do assert(predicate2(argument1, argument2) :- (clause1, clause2, clause3)).
(2) Another way to achieve this would be to introduce an extra argument for the predicate which you do not want to be called by the user and use it for an identification that the user cannot possibly provide, but which you can provide from your calling predicate. This might be a large constant number which looks random, or even a sentence. This even enables you to output a custom error message in case the wrong identification was provided.
Example:
predicate1 :-
predicate2("Identification: 2349860293587").
predicate2(Identification) :-
Identification = "Identification: 2349860293587",
1 < 5.
predicate2(Identification) :- Identification \= "Identification: 2349860293587",
write("Error: this procedure cannot be called by the user. Use predicate1/0 instead."),
fail.
I don't use the equivalent predicate2("Identification: 2349860293587") for the first clause of predicate2/0, because I'm not sure where the head of the clause might appear in Prolog messages and you don't want that. I use a fail in the end of the second clause just so that Prolog prints false instead of true after the error message. And finally, I have no idea how to prevent the user from looking up the source code with listing(predicate2) so that will still make it possible to simply look up the correct identification code if s/he really wants to. If it's just to keep the user from doing accidental harm, it should however suffice as a protection.
This reminds me to facility found in Java. There one can query the
curent call stack, and use this to regulate permissions of calling
a method. Translated to Prolog we find in the old DEC-10 Prolog the
following predicate:
ancestors(L)
Unifies L with a list of ancestor goals for the current clause.
The list starts with the parent goal and ends with the most recent
ancestor coming from a call in a compiled clause. The list is printed
using print and each entry is preceded by the invocation number in
parentheses followed by the depth number (as would be given in a
trace message). If the invocation does not have a number (this will
occur if Debug Mode was not switched on until further into the execution)
then this is marked by "-". Not available for compiled code.
Since the top level is usually a compiled predicate prolog/0, this could be
used to write a predicate that inspects its own call stack, and then decides
whether it wants to go into service or not.
rule2 :- ancestors(L), length(L,N), N<2, !, write('Don't call me'), fail.
rule2 :- 1<5.
In modern Prologs we don't find so often the ancestors/1 predicate anymore.
But it can be simulated along the following lines. Just throw an error, and
in case that the error is adorned with a stack trace, you get all you need:
ancestors(L) :- catch(sys_throw_error(ignore),error(ignore,L),true).
But beware stack eliminiation optimization might reduce the stack and thus
the list returned by ancestors/1.
Best Regards
P.S.: Stack elimination optimization is already explained here:
[4] Warren, D.H.D. (1983): An Abstract Prolog Instruction Set, Technical Note 309, SRI International, October, 1983
A discussion for Jekejeke Prolog is found here:
http://www.jekejeke.ch/idatab/doclet/prod/en/docs/10_pro08/13_press/03_bench/05_optimizations/03_stack.html