Execute a fact if the variable of previous fact has no result - prolog

I am implementing a Prolog program for trigonometric identities. This is a part of the program.
simplify_exp(Term1+Term2,X,Y) :- isolaxt(Term1+Term2,Y),
(nonvar(Y)-> simplify_exp(Term1,X,Y), simplify_exp(Term2,X,Y)).
isolaxt(sin(U)^2+cos(U)^2,1).
I want to execute the if statement only if Y has no value (when isolaxt is failed only). Even though I included nonvar(Y) it didn't work. How can it be done?

I don't really get if that's the only isolaxt clause you have or if you included it to exemplify.
Anyway, if isolaxt fails then simplify_exp will fail without reaching nonvar(Y).
Is that the behavior you expect? Perhaps you meant to use ; like so:
simplify_exp(Term1+Term2,X,Y) :-
isolaxt(Term1+Term2,Y); (simplify_exp(Term1,X,Y), simplify_exp(Term2,X,Y)).
This means either isolaxt will succeed or you're going to proceed with the calls to simplify_exp.
Also, note that nonvar(Y) will fail when isolaxt succeeds, so maybe you expected to use var(Y) instead.

Related

Why am I not getting a match?

I have a list structure called "stack".
At the point in my program which is causing problems, this is what stack holds:
stack([[s]],[np,[noun,john]])
I got this from running a trace, and its what stack is supposed to be holding.
When writing the next rule which is supposed to match this.
if
buffer([[Word|_]])
and aux(Word)
and stack([s],[np,[noun, john]])
If I do this then the rule executes as its supposed to. But I need to use a variable here instead of using "and stack([[s]],[np,[noun,john]])". However when I try to use anything else, the rule does not fire. I can't work out why. Other rules work fine when I use variables in the list.
Ive tried
stack([s]|Foo)
stack([s]|[Foo])
stack([MyHead]|[MyTail]... and literally every other combination I can think of.
I'm not entirely sure what is causing this problem
Your stack seems to have arity 2, where each arg is a list.
These aren't valid syntax for lists
stack([s]|Foo)
stack([s]|[Foo])
...
but since some Prolog declare the (|)/2 operator as alternative to (;)/2 (i.e. disjunction), you will not see any syntax error.
To understand you problem, you could try to unify, by mean of unification operator (=)/2
?- stack(S, Foo) = stack([[s]],[np,[noun,john]]).
you will get
S = [[s]]
Foo = [np,[noun,john]]

SWI-Prolog goal fail variable binding result

Is there any way that I can get a binding for a variable in Prolog even if the goal fails. I have a predicate where I am binding a variable with some value and after this I am failing the goal explicitly, but when I run the query it simply results in a fail without providing any biding for the variable. Something similar:
a(X) :-
X = 'something',
fail.
#Will Ness is correct (+1), assert can be used to capture bindings of variables as shown.
However, if you strictly need to retrieve bindings for variables in predicates like a and you know which parts could fail (and you don't care about them), then you could use combinations of cut (!) and true to permit a to proceed regardless. For example, consider:
a(X) :-
goalA(X), % a goal for which we definitely want a binding
(goalB, ! ; true). % an 'optional' goal which may fail
goalA('something').
goalB :- fail.
Executing this gives a('something'), even though goalB failed. Note that this isn't a commonly used way to program in Prolog, but if you know exactly what you're doing...
yes, this is how it is supposed to happen in Prolog. fail means the rejection of bindings made so far, because it says that these bindings are invalid, do not satisfy the goal.
but you can save some binding that will be undone on backtracking, with e.g. asserta predicate:
a(X) :-
X = 'something',
asserta(saved_x(X)),
fail.
Then, if you query saved_x(Z) afterwards, you will recover that value. Of course this is the part of Prolog that is extra-logical, i.e. outside of the logical programming paradigm.

Can I share variables in a catch call in Prolog?

I'm developing a task scheduler in Prolog. First of all let me show you a simplified version of my code. It goes like this:
handle_activable(As) :-
reset_flags,
findall(A,catch(activable(A),Exception,flag(marked_activable,A)),As),
activate_all(As).
There are two versions of activable/1 but the most relevant one is (again simplified):
activable(T) :-
task(T), /* T is a task */
inactive(T), /* The task is currently inactive */
(\+checked(T) ->
mark_checked(T),
!,
/*
Here would go the set of conditions
and statements to determine if task T
is activable or not. They may internally
call activable/1.
*/
asserta(flag(marked_activable,T))
;
/*
This task was already checked and the
result is stored in flag(marked_activable,T)
fact.
*/
throw(exception(already_checked,T))
).
The thing is that, within the "set-of-conditions-check",activable/1 might be indirectly called. That's why I need to use checked/1, in order to avoid unwanted loops.
I guessed the way I use findall/3 was okay, but since As is always instantiated as the empty list [] I'm starting to think there's something wrong with it.
The first thing I would like to ask you is the catch(...) call. Is it correct? I mean, if during an activable/1 call, the program throws an exception because the task has been already checked, would A still be instantiated (so that I can use it in flag(marked_activable,A))? If not, do you know any workaround for that?
The second thing I would like to ask you is about the correctness of my algorithm. I've been working on this for so long now and I did my best to have an efficient, robust and reliable code. The real hard thing is within the set-of-conditions check, where task's relations play a great role and create complex constrains. Do you think the way of "finding activable tasks" is a good one?
Using the built-in catch/3 predicate, the correct way for passing information is through the Catcher term.
catch(:Goal, +Catcher, :Recover)
According to SWI-Prolog doc, the Goal is the innermost goal for which Catcher unifies with the argument of throw/1, all choice points generated by Goal are cut and the system backtracks to the start of catch/3 while preserving the thrown exception term.
Thus, having a rule like:
generate(info1).
generate(info2).
generate(info3).
generate(info4).
rule(D) :-
generate(D),
...
throw(error_info(D)).
The result of catching this rule would be something like that:
?- catch(rule(D), Exception, write(Exception)).
error_info(info1).
Exception = error_info(info1).
?- catch(rule(_), error_info(E), write(E)).
info1.
E = info1.

Flowpattern doesn't exist

I have been working on a code in prolog for a while now and it is near compiling worthy and all my ideas seem to be solid so it should work when it compiles. It is a program that consults a database file for a list of clauses and then it awaits for a query by the user which it will then pick what information it needs from the sentence and query the database appropriately but there is a block of code that keeps giving me errors complaining that the flowpattern doesn't exist in the standard predicate this may be a silly question but even with all the looking into this I have done i can't find out how to fix this problem if someone could help me out or point me in the right direction that would be greatly appreciated.
Here is the block of code that gives the error:
loop(STR):-
scan(STR,LIST),
filter(LIST,LISroT1),
pars(LIST1,LIST2),
fail.
loop(STR):- STR >< "",readquery(L),loop(L).
readquery(QUERY):-nl,nl,write("Query: "),readln(QUERY).
scan(STR,[TOK|LIST]):-
fronttoken(STR,SYMB,STR1),!,
upper_lower(SYMB,TOK),
scan(STR1,LIST).
the specific line that the compiler complains about is fronttoken(STR,SYMB,STR),!,
any help will be apreaciated thanks!
Since we are looking at an "ex[c]er[p]t" of the code, it's hard to be sure what is going wrong, but the the given evidence points to this: loop/1 is being called before readquery/1 can do its work to populate (bind) the argument STR to loop/1.
Notice that loop/1 calls itself (recursively), and does so in a repeat/fail pattern. But the first time loop/1 runs, there's no indication in the code shown of how argument STR would get populated.
A clearer (more self-contained) code snippet would be like this:
loop :-
readquery(STR),
scan(STR,LIST),
filter(LIST,LISroT1),
pars(LIST1,LIST2),
fail.
loop :- loop.
This makes it clear that predicate loop doesn't actually return any result (and the given code snippet isn't complete enough to make clear what the program as a whole accomplishes). It assumes that the clauses ahead of fail in loop are deterministic, so that in failing, control passes through to the second (recursive) clause of loop/0. If this is not the case, the determinism could be forced by wrapping each call inside once/1.

How to stop prolog goal executing more than once?

I have a fact and a goal like below:
disconnected.
join :- disconnected, time(T), send(T).
Once this goal executes it should make disconnected false and thus not execute again. I am new to Prolog so I am a bit stuck. I am sure it's something really simple but can't figure it out at the moment. Any ideas?
You might use assert or retract to change the known facts. Or you might use global variables. I am not sure how standard that is.
The easiest would be to declare your join with two parameters: input parameter that signifies the current state, and an output parameter signifying the new state.

Resources