In PROLOG, How can I use assert recursively without getting 'true' result? - prolog

I'm planning to make new facts based on existing facts, by using assert.
However, the number of facts to be made will be more than 500, so that typing semicolon to go further steps become pretty tedious work.
thus I want to ignore or pass the 'true'(in the SWI PROLOG)
Are there any ways to deal with this?(ex. automatically pass all the 'true's...)
here's a part of my code
%initialize
initialize :-
discipline(X,Y),
assert(result(X,0)).
I have too many Xs in discipline(X,Y)..

maybe
?- forall(a_fact(F), your_fact_processing(F)).

In this specific case forall is actually preferred, but in general, in Prolog you have to rely on the language's mechanism for this kind of iteration. Here's an example for your case:
initialize:-
discipline(X,Y),
assert(result(X,0)),
fail.
initialize.
In this bit of code above, you are telling the interpreter that initialize should perform all the 'asserts' given possible disciplines through the backtracking mechanism. Unless you become really familiar with this, Prolog will never "click" for you.
Note that in this example initialize will never fail, even if there are no disciplines (and therefore no results) to assert. You'll need some extra work to detect edge-cases like that - which is why forall is actually preferred for this specific task of assertin many facts.
Also note that if it's good practice to not have singleton variables declared, you can use the notation where variables that you won't use start with the '_' (underscore) character.

Related

Does `setup_call_cleanup/3` detect determinism portably?

There is a very detailed Draft proposal for setup_call_cleanup/3.
Let me quote the relevant part for my question:
c) The cleanup handler is called exactly once; no later than upon failure of G. Earlier moments are:
If G is true or false, C is called at an implementation dependent moment after the last solution and after the last observable effect of G.
And this example:
setup_call_cleanup(S=1,G=2,write(S+G)).
Succeeds, unifying S = 1, G = 2.
Either: outputs '1+2'
Or: outputs on backtracking '1+_' prior to failure.
Or (?): outputs on backtracking '1+2' prior to failure.
In my understanding, this is basically because a unification is a
backtrackable goal; it simply fails on reexecution. Therefore, it is
up to the implementation to decide whether to call the cleanup just
after the fist execution (because there will be no more observable
effects of the goal), or postpone until the second execution of the
goal which now fails.
So it seems to me that this cannot be used to detect determinism
portably. Only a few built-in constructs like true, fail, !
etc. are genuinely non-backtrackable.
Is there any other way to check determinism without executing a goal twice?
I'm currently using SWI-prolog's deterministic/1, but I'd certainly
appreciate portability.
No. setup_call_cleanup/3 cannot detect determinism in a portable manner. For this would restrict an implementation in its freedom. Systems have different ways how they implement indexing. They have different trade-offs. Some have only first argument indexing, others have more than that. But systems which offer "better" indexing behave often quite randomly. Some systems do indexing only for nonvar terms, others also permit clauses that simply have a variable in the head - provided it is the last clause. Some may do "manual" choice point avoidance with safe tests prior to cuts and others just omit this. Brief, this is really a non-functional issue, and insisting on portability in this area is tantamount to slowing systems down.
However, what still holds is this: If setup_call_cleanup/3 detects determinism, then there is no further need to use a second goal to determine determinism! So it can be used to implement determinism detection more efficiently. In the general case, however, you will have to execute a goal twice.
The current definition of setup_call_cleanup/3 was also crafted such as to permit an implementation to also remove unnecessary choicepoints dynamically.
It is thinkable (not that I have seen such an implementation) that upon success of Call and the internal presence of a choicepoint, an implementation may examine the current choicepoints and remove them if determinism could be detected. Another possibility might be to perform some asynchronous garbage collection in between. All these options are not excluded by the current specification. It is unclear if they will ever be implemented, but it might happen, once some applications depend on such a feature. This has happened in Prolog already a couple of times, so a repetition is not completely fantasy. In fact I am thinking of a particular case to help DCGs to become more determinate. Who knows, maybe you will go that path!
Here is an example how indexing in SWI depends on the history of previous queries:
?- [user].
p(_,a). p(_,b). end_of_file.
true.
?- p(1,a).
true ;
false.
?- p(_,a).
true.
?- p(1,a).
true. % now, it's determinate!
Here is an example, how indexing on the second argument is strictly weaker than first argument indexing:
?- [user].
q(_,_). q(0,0). end_of_file.
true.
?- q(X,1).
true ; % weak
false.
?- q(1,X).
true.
As you're interested in portability, Logtalk's lgtunit tool defines a portable deterministic/1 predicate for 10 of its supported backend Prolog compilers:
http://logtalk.org/library/lgtunit_0.html
https://github.com/LogtalkDotOrg/logtalk3/blob/master/tools/lgtunit/lgtunit.lgt (starting around line 1051)
Note that different systems use different built-in predicates that approximate the intended functionality.

Prolog: Can you make a predicate behave differently depending on whether a value is ground or not?

I have a somewhat complex predicate with four arguments that need to work when both the first and last arguments are ground/not ground, not ground/ground or ground/ground, and the second and third arguments are ground.
i.e. predicate(A,B,C,D).
I can't provide my actual code since it is part of an assignment.
I have it mostly working, but am receiving instantiation errors when A is not ground, but D is. However, I have singled out a line of code that is causing issues. When I change the goal order of the predicate, it works when D is ground and A is not, but in doing so, it no longer works for when A is ground and D is not. I'm not sure there is a way around this.
Is there a way to use both lines of code so that if the A is ground for instance it will use the first line, but if A is not ground, it will use the second, and ignore the first? And vice versa.
You can do that, but, almost invariably, you will break the declarative semantics of your programs if you do that.
Consider a simple example to see how such a non-monotonic and extra-logical predicate already breaks basic assumptions and typical declarative properties of well-known predicates, like commutativity of conjunction:
?- ground(X), X = a.
false.
But, if we simply exchange the goals by commutativity of conjunction, we get a different answer:
?- X = a, ground(X).
X = a.
For this reason, such meta-logical predicates are best avoided, especially if you are just beginning to learn the language.
Instead, better stay in the pure and monotonic subset of Prolog. Use constraints like dif/2 and CLP(FD) to make your programs usable in all directions, increasing generality and ease of understanding.
See logical-purity, prolog-dif and clpfd for more information.

Prolog: How to tell if a predicate is deterministic or not

So from what I understand about deterministic predicates:
Deterministic predicate = 1 solution
Non-deterministic predicate = multiple solutions
Are there any type of rules as to how you can detect if the predicate is one or the other? Like looking at the search tree, etc.
There is no clear, generally accepted consensus about these notions. However, they are usually based rather on the observed answers and not based on the number of solutions. In certain contexts the notions are very implementation related. Non-determinate may mean: leaves a choice point open. And sometimes determinate means: never even creates a choice point.
Answers vs. solutions
To see the difference, consider the goal length(L, 1). How many solutions does it have? L = [a] is one, L = [23] another... but all of these solutions are compactly represented with a single answer substitution: L = [_] which thus contains infinitely many solutions.
In any case, in all implementations I know of, length(L, 1) is a determinate goal.
Now consider the goal repeat which has exactly one solution, but infinitely many answers. This goal is considered non-determinate.
In case you are interested in constraints, things become even more evolved. In library(clpfd), the goal X #> Y, Y #> X has no solution, but still one answer. Combine this with repeat: infinitely many answers and no solution.
Further, the goal append(Xs, Ys, []) has exactly one solution and also exactly one answer, nevertheless it is considered non-determinate in many implementations, since in those implementations it leaves a choice point open.
In an ideal implementation, there would be no answers without solutions (except false), and there would be non-determinism only when there is more than one answer. But then, all of this is mostly undecidable in the general case.
So, whenever you are using these notions make sure on what level things are meant. Rather explicitly say: multiple answers, multiple solutions, leaves no (unnecessary) choice point open.
You need understand the difference between det, semidet and undet, it is more than just number of solutions.
Because there is no loop control operator in Prolog, looping (not recursion) is constructed as a 'sequence generating' predicate (undet) followed by the loop body. Also you can store solutions with some of findall-group predicates as a list and loop later with the member/2 predicate.
So, any piece of your program is either part of loop construction or part of usual flow. So, there is a difference in designing det and undet predicates almost in the intended usage. If you can work with a sequence you always do undet and comment it as so. There is a nice unit-test extension in swi-prolog which can check wheter your predicate always the same in mean of det/semidet/undet (semidet is for usage the same way as undet but as a head of 'if' construction).
So, the difference is pre-design, and this question should not be arised with already existing predicates. It is a good practice always comment the intended usage in a comment like.
% member(?El, ?List) is undet.
Deterministic: Always succeeds with a single answer that is always the same for the same input. Think a of a static list of three items, and you tell your function to return value one. You will get the same answer every time. Additionally, arithmetic functions. 1 + 1 = 2. X + Y = Z.
Semi-deterministic: Succeeds with a single answer that is always the same for the same input, but it can fail. Think of a function that takes a list of numbers, and you ask your function if some number exists in the list. It either does, or it doesn't, based on the contents of the list given and the number asked.
Non-deterministic: Succeeds with a single answer, but can exhibit different behaviors on different runs, even for the same input. Think any kind of math.random(min,max) function like random/3
In essence, this is entirely separate from the concept of choice points, as choice points are a function of Prolog. Where I think the Prolog confusion of these terms comes from is that Prolog can find a single answer, then go back and try for another solution, and you have to use the cut operator ! to tell it that you want to discard your choice points explicitly.
This is very useful to know when working with Prolog Unit Testing

How to avoid using assert and retractall in Prolog to implement global (or state) variables

I often end up writing code in Prolog which involves some arithmetic calculation (or state information important throughout the program), by means of first obtaining the value stored in a predicate, then recalculating the value and finally storing the value using retractall and assert because in Prolog we cannot assign values to variable twice using is (thus making almost every variable that needs modification, global). I have come to know that this is not a good practice in Prolog. In this regard I would like to ask:
Why is it a bad practice in Prolog (though i myself don't like to go through the above mentioned steps just to have have a kind of flexible (modifiable) variable)?
What are some general ways to avoid this practice? Small examples will be greatly appreciated.
P.S. I just started learning Prolog. I do have programming experience in languages like C.
Edited for further clarification
A bad example (in win-prolog) of what I want to say is given below:
:- dynamic(value/1).
:- assert(value(0)).
adds :-
value(X),
NewX is X + 4,
retractall(value(_)),
assert(value(NewX)).
mults :-
value(Y),
NewY is Y * 2,
retractall(value(_)),
assert(value(NewY)).
start :-
retractall(value(_)),
assert(value(3)),
adds,
mults,
value(Q),
write(Q).
Then we can query like:
?- start.
Here, it is very trivial, but in real program and application, the above shown method of global variable becomes unavoidable. Sometimes the list given above like assert(value(0))... grows very long with many more assert predicates for defining more variables. This is done to make communication of the values between different functions possible and to store states of variables during the runtime of program.
Finally, I'd like to know one more thing:
When does the practice mentioned above become unavoidable in spite of various solutions suggested by you to avoid it?
The general way to avoid this is to think in terms of relations between states of your computations: You use one argument to hold the state that is relevant to your program before a calculation, and a second argument that describes the state after some calculation. For example, to describe a sequence of arithmetic operations on a value V0, you can use:
state0_state(V0, V) :-
operation1_result(V0, V1),
operation2_result(V1, V2),
operation3_result(V2, V).
Notice how the state (in your case: the arithmetic value) is threaded through the predicates. The naming convention V0 -> V1 -> ... -> V scales easily to any number of operations and helps to keep in mind that V0 is the initial value, and V is the value after the various operations have been applied. Each predicate that needs to access or modify the state will have an argument that allows you to pass it the state.
A huge advantage of threading the state through like this is that you can easily reason about each operation in isolation: You can test it, debug it, analyze it with other tools etc., without having to set up any implicit global state. As another huge benefit, you can then use your programs in more directions provided you are using sufficiently general predicates. For example, you can ask: Which initial values lead to a given outcome?
?- state0_state(V0, given_outcome).
This is of course not readily possible when using the imperative style. You should therefore use constraints instead of is/2, because is/2 only works in one direction. Constraints are much easier to use and a more general modern alternative to low-level arithmetic.
The dynamic database is also slower than threading states through in variables, because it performs indexing etc. on each assertz/1.
1 - it's bad practice because destroys the declarative model that (pure) Prolog programs exhibit.
Then the programmer must think in procedural terms, and the procedural model of Prolog is rather complicate and difficult to follow.
Specifically, we must be able to decide about the validity of asserted knowledge while the programs backtracks, i.e. follow alternative paths to those already tried, that (maybe) caused the assertions.
2 - We need additional variables to keep the state. A practical, maybe not very intuitive way, is using grammar rules (a DCG) instead of plain predicates. Grammar rules are translated adding two list arguments, normally hidden, and we can use those arguments to pass around the state implicitly, and reference/change it only where needed.
A really interesting introduction is here: DCGs in Prolog by Markus Triska. Look for Implicitly passing states around: you'll find this enlighting small example:
num_leaves(nil), [N1] --> [N0], { N1 is N0 + 1 }.
num_leaves(node(_,Left,Right)) -->
num_leaves(Left),
num_leaves(Right).
More generally, and for further practical examples, see Thinking in States, from the same author.
edit: generally, assert/retract are required only if you need to change the database, or keep track of computation result along backtracking. A simple example from my (very) old Prolog interpreter:
findall_p(X,G,_):-
asserta(found('$mark')),
call(G),
asserta(found(X)),
fail.
findall_p(_,_,N) :-
collect_found([],N),
!.
collect_found(S,L) :-
getnext(X),
!,
collect_found([X|S],L).
collect_found(L,L).
getnext(X) :-
retract(found(X)),
!,
X \= '$mark'.
findall/3 can be seen as the basic all solutions predicate. That code should be the very same from Clockins-Mellish textbook - Programming in Prolog. I used it while testing the 'real' findall/3 I implemented. You can see that it's not 'reentrant', because of the '$mark' aliased.

left_of exercise from The Art Of Prolog

In the book we are asked to define the predicates left_of, right_of, above, and below using the following layout.
% bike camera
% pencil hourglass butterfly fish
left_of(pencil, hourglass).
left_of(hourglass, butterfly).
left_of(butterfly, fish).
above(bike, pencil).
above(camera, butterfly).
right_of(Obj1, Obj2) :-
left_of(Obj2, Obj1).
below(Obj1, Obj2) :-
above(Obj2, Obj1).
This seems to find correct solutions.
Later in the book we are asked to add a recursive rule for left_of. The only solution I could find is to use a different functor name: left_of2. So I've basically reimplemented the ancestor relationship.
left_of2(Obj1, Obj2) :-
left_of(Obj1, Obj2).
left_of2(Obj1, Obj2) :-
left_of(Obj1, X),
left_of2(X, Obj2).
In my attempts to reuse left_of, I can get all the correct solution but on the final redo, a stack overflow occurs. I'm guessing that's because I don't have a correct base case defined. Can this be coded using left_of for facts and a recursive procedure?
As mentioned in the comments, it is an unfortunate fact that in Prolog you must have separately named predicates to do this. If you don't, you'll wind up with something that looks like this:
left_of(X,Z) :- left_of(X,Y), left_of(Y,Z).
which gives you unbounded recursion twice. There's nothing wrong in principle with facts and predicates sharing the same name--in fact, it's pretty common for a base case rule to look like a fact. It's just that handling a transitive closure situation like this results in stack overflows unless one of the two steps is finite, and there's no other way to ensure that in Prolog than by naming them separately.
This is far from the only case in Prolog where you are compelled to break work down into separate predicates. Other commonly-occurring cases include computational loops with initializers or finalizers.
Conventionally one would wind up naming the predicate differently from the fact. For instance, directly_left_of for the facts and left_of for the predicate. Using the module system or Logtalk you can easily hide the "direct" version and encourage your users to use the transitive version. You can also make the intention more explicit without disallowing it by using an uncomfortable name for the hidden one, like left_of_.
In other languages, a function is a more opaque, larger sort of abstraction and there are facilities for hiding considerable work behind one. Prolog's predicates, by comparison, are "simpler," which used to bother me. Nowadays I'm glad that they're simpler because there's enough other stuff going on that I'm glad I don't also have to figure out variable-arity predicates or keyword arguments (though you can easily simulate both with lists, if you need to).

Resources