Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

All Quantifier

0 views
Skip to first unread message

Michael Igler

unread,
Jun 20, 2008, 2:21:12 AM6/20/08
to
I try to simulate some process flow with prolog.

It almost works, but I have some problems with the all quantifier.
The code is:

:- dynamic done/1.
:- op(900, xfx, =>).
:- op(800, xfy, &).
:- op(300, xfx, :).


% black_edge and so black_conn connecting two processes
black_conn(X,Y) :- black_edge(X,Z), black_conn(Z,Y).
black_conn(X,Y) :- black_edge(X,Y).

% red_conn connecting two processes
red_conn(X,Y) :- red_edge(X,Y).

% Now A shall also be required in order to execute C:
% A -black-> B -red-> C ==implies==> A -red-> C
red_conn(X,Z) :- black_conn(X,Y), red_conn(Y,Z).


% Is a process executable?
executable(X) :- black_conn(X,_).
executable(Y) :- black_conn(_,Y).
executable(X) :- red_conn(X,_).

% Now I need that executable(c) is only possible if done(a) AND done(b)
% holds
% Something with all?
% all(X):(red_conn(X,Y) & done(X) => executable(Y)).

% The following works in the way that done(a) OR done(b) is sufficient
% for executable(c) but not both what I want
executable(Y) :- red_conn(X,Y), done(X).


% MODEL FLOW
% A -black-> B -red-> C
black_edge(a,b).
red_edge(b,c).


% QUERIES
% executable(c). --> NO

% assert(done(a)).

% executable(c). --> Shall be NO but is YES

% assert(done(b)).

% executable(c). --> Shall be YES after done(b)

Best reagrds,

Michael


Geoffrey Summerhayes

unread,
Jun 20, 2008, 11:08:31 AM6/20/08
to
On Jun 20, 2:21 am, michael.ig...@web.de (Michael Igler) wrote:
> I try to simulate some process flow with prolog.
>
> It almost works, but I have some problems with the all quantifier.
> The code is:
>
> :- dynamic done/1.
> :- op(900, xfx, =>).
> :- op(800, xfy, &).
> :- op(300, xfx, :).
>
> % black_edge and so black_conn connecting two processes
> black_conn(X,Y) :- black_edge(X,Z), black_conn(Z,Y).
> black_conn(X,Y) :- black_edge(X,Y).
>
> % red_conn connecting two processes
> red_conn(X,Y) :- red_edge(X,Y).
>
> % Now A shall also be required in order to execute C:
> % A -black-> B -red-> C ==implies==> A -red-> C
> red_conn(X,Z) :- black_conn(X,Y), red_conn(Y,Z).
>
> % Is a process executable?
> executable(X) :- black_conn(X,_).
> executable(Y) :- black_conn(_,Y).
> executable(X) :- red_conn(X,_).
>
> % Now I need that executable(c) is only possible if done(a) AND done(b)
> % holds
> % Something with all?
> % all(X):(red_conn(X,Y) & done(X) => executable(Y)).

Perhaps,

executable(Y) :- \+ (red_conn(X,Y),\+ done(X)).

---
Geoff

Michael Igler

unread,
Jun 23, 2008, 2:28:06 AM6/23/08
to
Hi Geoff,

yes, that's it. Many thanxs.

The working code:

:- dynamic done/1.

% black_edge and so black_conn connecting two processes
black_conn(X,Y) :- black_edge(X,Z), black_conn(Z,Y).
black_conn(X,Y) :- black_edge(X,Y).

% red_conn connecting two processes
red_conn(X,Y) :- red_edge(X,Y).

% Now A shall also be required in order to execute C:
% A -black-> B -red-> C ==implies==> A -red-> C
red_conn(X,Z) :- black_conn(X,Y), red_conn(Y,Z).


% Is a process executable?
executable(X) :- black_conn(X,_).
executable(Y) :- black_conn(_,Y).
executable(X) :- red_conn(X,_).

% A process that is connected through a red edge
% shall only be executable if all preceding processes
% have been executed


executable(Y) :- \+ (red_conn(X,Y),\+ done(X)).


% MODEL FLOW
% A -black-> B -black-> C -black-> D -red-> E
black_edge(a,b).
black_edge(b,c).
black_edge(c,d).
red_edge(d,e).


% QUERIES
% executable(e). --> NO

% assert(done(a)).
% assert(done(b)).
% assert(done(c)).
% assert(done(d)).

% executable(e). --> YES


Michael

Geoffrey Summerhayes

unread,
Jun 23, 2008, 11:51:49 AM6/23/08
to

Try removing the other executable declarations.

:- dynamic done/1.

black_conn(X,Y) :- black_edge(X,Z), black_conn(Z,Y).
black_conn(X,Y) :- black_edge(X,Y).

red_conn(X,Y) :- red_edge(X,Y).
red_conn(X,Z) :- black_conn(X,Y), red_conn(Y,Z).

executable(Y) :- \+ (red_conn(X,Y),\+ done(X)).

black_edge(a,b).
black_edge(b,c).
black_edge(c,d).
red_edge(d,e).

And make sure that executable/1 does what you
want it to, it allows more than you might think.
Try executable(f).

----
Geoff

Michael Igler

unread,
Jun 25, 2008, 8:17:28 AM6/25/08
to
Geoffrey Summerhayes <sum...@gmail.com> wrote:


Yes it is still working.

I wonder for 2 days now what the meaning of \+ is.
Sicstus Manual says:

\+ P : Fails if the goal P has a solution, and succeeds otherwise.
This is not real negation ("P is false"), but a kind of pseudo-negation
meaning "P is not provable".

But I have no idea how it is applicable to my case.


Michael

Michael Igler

unread,
Jul 16, 2008, 5:20:34 AM7/16/08
to
Michael Igler <michae...@web.de> wrote:


I have modified my program and added a statement that gives me a set of
processes that I can execute :

:- dynamic done/1.

% black_edge and so black_conn connecting two processes
black_conn(X,Y) :- black_edge(X,Z), black_conn(Z,Y).
black_conn(X,Y) :- black_edge(X,Y).

% red_conn connecting two processes
red_conn(X,Y) :- red_edge(X,Y).

% Now A shall also be required in order to execute C:
% A -black-> B -red-> C ==implies==> A -red-> C
red_conn(X,Z) :- black_conn(X,Y), red_conn(Y,Z).

% Is a process executable?
executable(X) :- black_conn(X,_).
executable(Y) :- black_conn(_,Y).
executable(X) :- red_conn(X,_).

% Now I need that executable(c) is only possible if done(a) AND done(b)
holds
executable(X) :- \+ (red_conn(W,X),\+ done(W)).


% Give a list of processes that are excutable
canDo :- setof(X, executable(X), Ausfuehrbar), write('You can do = '),
write(Ausfuehrbar),nl.


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% INSTANCE
% MODEL FLOW
% A -black-> B -red-> C
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
black_edge(a,b).
red_edge(b,c).

The following prolog session illustrates my problem:

?- canDo.
You can do = [a, b]
true.

?- assert(done(a)).
true.

?- assert(done(b)).
true.

?- canDo.
You can do = [_G327, a, b]
true.

Why is there a _G327 and not 'c', and how can I resolve this problem?


Thanks for tips,


Michael

Geoffrey Summerhayes

unread,
Jul 16, 2008, 4:21:26 PM7/16/08
to

Because executable(X) :- \+ (red_conn(W,X),\+ done(W)). says
EVERYTHING is executable unless X has a red predecessor which
isn't done.

If X is unified before calling executable/1, it will always
succeed unless it fails that restriction. If X is always
unified before calling executable/1, there is no need for
the other clauses. This is the way the clause was designed.

In fact, there may be a bit of a problem leaving the other clauses
intact. Consider [black_edge(a,c). red_edge(b,c).], executable(c).
will succeed due to the black connection to a when you most
likely want it to fail without done(b).

But that's hard to say without a better idea of what red and
black edges are supposed to mean. I'll also mention the case of a
solid set of red edges.

i.e.
Given
red_edge(a,b).
red_edge(b,c).
done(b).

Should executable(c). pass or fail?

If X isn't unified when calling executable/1 is a trickier case
for the last clause, but if it can find one unification that fails
the whole clause fails, if it cannot find one then X can be anything
and the generic place (_G###) returned is actually correct.

So unifying to a possible X first, then going through the
rest of the clause, one solution.

process(a).
process(b).
process(c).

% one clause for executable
executable(X) :- process(X), \+ (red_conn(W,X),\+ done(W)).

The advantage to this is that processes that are unconnected
will show up as executable.

Another approach:

% changed from executable/1
connected(X) :- black_conn(X,_).
connected(Y) :- black_conn(_,Y).
connected(X) :- red_conn(X,_).
connected(X) :- red_conn(_,X). % added case

% one clause for executable
executable(X) :- connected(X), \+ (red_conn(W,X),\+ done(W)).

---
Geoff

Michael Igler

unread,
Jul 21, 2008, 4:57:20 AM7/21/08
to
Geoffrey Summerhayes <sum...@gmail.com> wrote:


Now everything is working as I want to. Thanks!
By the way, I choosed your second approach, beacuse all processes
shall always be connected.


Is it possible to put some quantifications on the processes, e.g.
process a may be executed minimum twice and maximum 3 times,
A : {2,3}

Now when I take :

A --red--> B beside the constraint that A has to be executed before B,
the quantification constraint that A is in 2..3 has to be fullfilled
too.

So I need to do assert(done(a)) twice in order that executale(b) says
"true".

I wonder which data-structure I shall take. Model {2,3} as interval and
check if the counter of process A is in that interval?

And when I do a assert(done(a)) and A is already done 3 times the it
shall say "fail".


Michael


0 new messages