| Register | FAQ | Calendar | Search | Today's Posts | Mark Forums Read |
|
#1
| |||
| |||
| I have a small Prolog program that models how a process flow with two different connectives(dashed arrows, solid arrows) can be modeled within Prolog: :- dynamic done/1. % dashed_edge is symmetric and transitive dashed_conn(X,Y) :- dashed_arrow(X,Y). dashed_conn(X,Z) :- dashed_arrow(Y,Z), dashed_conn(X,Y). % solid_conn connecting two processes solid_conn(X,Y) :- solid_arrow(X,Y). % All prevois processes must be completed if there is a solid connection % A -dashed-> B -solid-> C ==implies==> A -solid-> C solid_conn(X,Z) :- dashed_conn(X,Y), solid_conn(Y,Z). % define connection connected(X) :- dashed_conn(X,_). connected(Y) :- dashed_conn(_,Y). connected(X) :- solid_conn(X,_). connected(X) :- solid_conn(_,X). % one clause for executable % \+P: Fails if P has solution, succeeds otherwise executable(X) :- connected(X), \+ (solid_conn(W,X),\+ done(W)). % set of processes that are excutable canDo :- setof(X, executable(X), Ausfuehrbar), write('You can do = '), write(Ausfuehrbar),nl. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % INSTANCE % MODEL FLOW % A -dashed-> B -dashed-> C -solid-> D %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% dashed_arrow(a,b). dashed_arrow(b,c). solid_arrow(c,d). %A in 2..3. %B in 3..4. %C in 1..2. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % QUERIES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % canDo. % You can do = [a, b, c] % assert(done(a)). % assert(done(b)). % assert(done(c)). % canDo. % You can do = [a, b, c, d] Now my question: 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} (in Prolog A in 2..3 ????) Now when I take : A --solid--> 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 have taken a look to :- use_module(library(clpfd)). Is it the right way to use constraint programming over finite domains for this purpose? I have also wondered if I shall model a process with Logtalk, so I can put the things better together in one object(process). Later there will be things like the person who is doing the process, etc. Michael |
|
#2
| |||
| |||
| michael.igler@web.de (Michael Igler) writes: > A --solid--> 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". If A is in 2..3, then A itself already reflects the number of necessary and possible executions of this task. In any ground solution, A will be either 2 or 3, and there seems to be no need to use assert/1 here. Also, you can use reified constraints to obtain truth values, for example: ?- A in 2..3 #<==> B_executable, A #= 1. %@ A = 1, %@ B_executable = 0. ?- A in 2..3 #<==> B_executable, A #= 3. %@ A = 3, %@ B_executable = 1. -- comp.lang.prolog FAQ: http://www.logic.at/prolog/faq/ |
|
#3
| |||
| |||
| Markus Triska <triska@logic.at> wrote: > michael.igler@web.de (Michael Igler) writes: > > > A --solid--> 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". > > If A is in 2..3, then A itself already reflects the number of necessary > and possible executions of this task. In any ground solution, A will be > either 2 or 3, and there seems to be no need to use assert/1 here. Also, > you can use reified constraints to obtain truth values, for example: > > ?- A in 2..3 #<==> B_executable, A #= 1. > %@ A = 1, > %@ B_executable = 0. > > ?- A in 2..3 #<==> B_executable, A #= 3. > %@ A = 3, > %@ B_executable = 1. What I did so far is the following: :- use_module(library(clpfd)). :- dynamic counter_process/2. :- dynamic domain_process/3. % black_edge is transitive black_conn(X,Y) :- black_edge(X,Y). black_conn(X,Z) :- black_edge(Y,Z), black_conn(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). % define connection connected(X) :- black_conn(X,_). connected(X) :- black_conn(_,X). connected(X) :- red_conn(X,_). connected(X) :- red_conn(_,X). % inrease the counter of a process if it is possible inc(Proc) :- counter_process(Proc, N), CP is N+1, domain_process(Proc, _, MAX), CP #=< MAX, retract(counter_process(Proc, N)), assert(counter_process(Proc, CP)). % checks if the counter of a process can be increased increasable(Proc) :- counter_process(Proc, N), domain_process(Proc, _, MAX), N #< MAX. % check if process is within its given domain procInDomain(Proc) :- counter_process(Proc, CP), domain_process(Proc, MIN, MAX), CP #>= MIN, CP #=< MAX. % one clause for executable % \+P: Fails if P has a solution, succeeds otherwise executable(X) :- connected(X), \+ (red_conn(W,X),\+ procInDomain(W)), increasable(X). % set 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). black_edge(b,c). black_edge(c,d). black_edge(d,e). counter_process(a, 0). counter_process(b, 0). counter_process(c, 0). counter_process(d, 0). counter_process(e, 0). domain_process(a, 1, 2). domain_process(b, 3, 4). domain_process(c, 2, 4). domain_process(d, 2, 2). domain_process(e, 1, 1). Now as you can see in the INSTANCE there are only black_edges a,b,..., e. This is a problem as there would only red_edges. Prolog gives me the error : red_conn/2: Undefined procedure: red_edge/2 As I only tried a mixture between red_edgea and black_edges so far the error never occured yet. The problem is the conected or the deinition of the red_edge, I do not know. Is there are basic-case missing ? Michael |
|
#4
| |||
| |||
| Michael Igler <michael.igler@web.de> wrote: > Markus Triska <triska@logic.at> wrote: > > > michael.igler@web.de (Michael Igler) writes: > > > > > A --solid--> 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". > > > > If A is in 2..3, then A itself already reflects the number of necessary > > and possible executions of this task. In any ground solution, A will be > > either 2 or 3, and there seems to be no need to use assert/1 here. Also, > > you can use reified constraints to obtain truth values, for example: > > > > ?- A in 2..3 #<==> B_executable, A #= 1. > > %@ A = 1, > > %@ B_executable = 0. > > > > ?- A in 2..3 #<==> B_executable, A #= 3. > > %@ A = 3, > > %@ B_executable = 1. > > > > > What I did so far is the following: > > :- use_module(library(clpfd)). > > :- dynamic counter_process/2. > :- dynamic domain_process/3. > > > % black_edge is transitive > black_conn(X,Y) :- black_edge(X,Y). > black_conn(X,Z) :- black_edge(Y,Z), black_conn(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). > > > % define connection > connected(X) :- black_conn(X,_). > connected(X) :- black_conn(_,X). > connected(X) :- red_conn(X,_). > connected(X) :- red_conn(_,X). > > > % inrease the counter of a process if it is possible > inc(Proc) :- counter_process(Proc, N), > CP is N+1, > domain_process(Proc, _, MAX), > CP #=< MAX, > retract(counter_process(Proc, N)), > assert(counter_process(Proc, CP)). > > > % checks if the counter of a process can be increased > increasable(Proc) :- counter_process(Proc, N), > domain_process(Proc, _, MAX), > N #< MAX. > > > % check if process is within its given domain > procInDomain(Proc) :- counter_process(Proc, CP), > domain_process(Proc, MIN, MAX), > CP #>= MIN, > CP #=< MAX. > > > % one clause for executable > % \+P: Fails if P has a solution, succeeds otherwise > executable(X) :- connected(X), \+ (red_conn(W,X),\+ procInDomain(W)), > increasable(X). > > > % set 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). > black_edge(b,c). > black_edge(c,d). > black_edge(d,e). > > counter_process(a, 0). > counter_process(b, 0). > counter_process(c, 0). > counter_process(d, 0). > counter_process(e, 0). > > domain_process(a, 1, 2). > domain_process(b, 3, 4). > domain_process(c, 2, 4). > domain_process(d, 2, 2). > domain_process(e, 1, 1). > > > Now as you can see in the INSTANCE there are only black_edges a,b,..., > e. This is a problem as there would only red_edges. Prolog gives me the > error : > > red_conn/2: Undefined procedure: red_edge/2 > > As I only tried a mixture between red_edgea and black_edges so far the > error never occured yet. > > > The problem is the conected or the deinition of the red_edge, I do not > know. > > Is there are basic-case missing ? > > > Michael I added :- dynamic black_edge/2. :- dynamic red_edge/2. Is that a good solution to do so? Because it works now :-) Michael |
|
#5
| |||
| |||
| Michael Igler wrote: > ... > I have taken a look to :- use_module(library(clpfd)). > Is it the right way to use constraint programming over finite domains > for this purpose? > > I have also wondered if I shall model a process with Logtalk, so I can > put the things better together in one object(process). Later there will > be things like the person who is doing the process, etc. The current Logtalk development version allows you to use use_module/2 directives in objects, thus allowing module predicates to be called using implicit qualification, improving readability. For example: :- object(puzzle). :- public(puzzle/1). :- use_module(clpfd, [all_different/1, ins/2, label/1, (#=)/2, (#\=)/ 2]). :- initialization((puzzle(As+Bs=Cs), label(As), write(As+Bs=Cs), nl)). puzzle([S,E,N,D] + [M,O,R,E] = [M,O,N,E,Y]) :- Vars = [S,E,N,D,M,O,R,Y], Vars ins 0..9, all_different(Vars), S*1000 + E*100 + N*10 + D + M*1000 + O*100 + R*10 + E #= M*10000 + O*1000 + N*100 + E*10 + Y, M #\= 0, S #\= 0. :- end_object. Cheers, Paulo |
![]() |
| Thread Tools | |
| Display Modes | |
In an effort to better serve ads to our visitors, cookies are used on objectmix.com. For more information, check out our Privacy Policy.