Prolog graph path search with cyclic path - path

I am a complete newbie in Prolog. I am trying to figure out a problem where I need to check if path is present between edges. I am done with acyclic graph code for cyclic my code is going to infinite loop.
path(Start, End) :- edge(Start, End).
path(Start, End) :- edge(Start, Z), path(Z, End).
I need to handle this case by defining a new predicate:
new_path(Start,End,path)
which should eliminate infinite loop. Please let me know how to proceed with it.

Try
path(Start, End) :-
closure(edge, Start, End).
using this definition for closure/3

You need to keep track of what nodes you've visited as you go, using a prolog list as a LIFO stack. Something along these lines:
path( A , Z , P ) :- % to find a path from A to Z
traverse( A , Z , [] , P ) , % take a walk, visiting A to see if we can get to Z, seeding the visited list with the empty string.
reverse(P,Path) % once we find a path, let's reverse it, since it's in LIFO order.
. % That's all there is to it, really.
traverse( Z , Z , V , [Z|V] ) % if current node is the destination node, we've arrived.
. % - just push the destination vertice onto the visited list and unify that with the path
traverse( A , Z , V , P ) :- % Otherwise...
edge( A , Z ) , % - if the current node is directly connected to the destination node,
traverse( Z , Z , [A|V] , P) % - go visit the destination, marking the current node as visited
. %
traverse( A, Z , V , P ) :- % Otherwise...
A \= Z,
edge( A , B ) , % - if the current node is connected to a node
B \= Z , % - that is not the destination node, and
unvisited([A|V],B) , % - we have not yet visited that node,
traverse( B , Z , [A|V] , P ) % - go visit the intermediate node, marking the current node as visited.
. % Easy!
unvisited( [] , _ ) . % We succeed if the visited list is empty.
unvisited( [A|_] , A ) :- ! , fail . % We fail deterministically if we find the node in the visited list.
unvisited( [_|L] , A ) :- unvisited(L,A) . % otherwise, we keep looking.

Related

How to count locals in ANS-Forth?

While developing BigZ, mostly used for number theoretical experiments, I've discovered the need of orthogonality in the word-set that create, filter or transform sets. I want a few words that logically combinated cover a wide range of commands, without the need to memorize a large number of words and ways to combinate them.
1 100 condition isprime create-set
put the set of all prime numbers between 1 and 100 on a set stack, while
function 1+ transform-set
transform this set to the set of all numbers p+1, where p is a prime less than 100.
Further,
condition sqr filter-set
leaves the set of all perfect squares on the form p+1 on the stack.
This works rather nice for sets of natural numbers, but to be able to create, filter and transform sets of n-tuples I need to be able to count locals in unnamed words. I have redesigned words to shortly denote compound conditions and functions:
: ~ :noname ;
: :| postpone locals| ; immediate
1 100 ~ :| p | p is prime p 2 + isprime p 2 - isprime or and ;
1 100 ~ :| a b | a dup * b dup * + isprime ;
Executing this two examples gives the parameter stack ( 1 100 xt ) but to be able to handle this right, in the first case a set of numbers and in the second case a set of pairs should be produced, I'll have to complement the word :| to get ( 1 100 xt n ) where n is the numbet of locals used. I think one could use >IN and PARSE to do this, but it was a long time ago I did such things, so I doubt I can do it properly nowadays.
I didn't understand (LOCALS) but with patience and luck I managed to do it with my original idea:
: bl# \ ad n -- m
over + swap 0 -rot
do i c# bl = +
loop negate ;
\ count the number of blanks in the string ad n
variable loc#
: locals# \ --
>in # >r
[char] | parse bl# loc# !
r> >in ! ; immediate
\ count the number of locals while loading
: -| \ --
postpone locals#
postpone locals| ; immediate
\ replace LOCALS|
Now
: test -| a b | a b + ;
works as LOCALS| but leave the number of locals in the global variable loc#.
Maybe you should drop LOCALS| and parse the local variables yourself. For each one, call (LOCAL) with its name, and end with passing an empty string.
See http://lars.nocrew.org/dpans/dpans13.htm#13.6.1.0086 for details.

Duplicated output in Maxima

I implemented the bubble sort method in Maxima as:
burbuja(l) := block(
for i : 1 step 1 thru length(l) do (
for j : length(l) - 1 step -1 while j >= i do (
if l[j] > l[j + 1] then (
elemento : l[j],
l[j] : l[j + 1],
l[j + 1] : elemento
)
)
), print(l)
);
The problem is that the output is something like this:
(%i1) burbuja([3,2,1]);
[1, 2, 3]
(%o1) [1, 2, 3]
If I remove print(l) from the penultimate line, this is the output:
(%i1) burbuja([3,2,1]);
(%o1) done
The question is how can I print the result without duplicating it?
Thanks.
Instead of print(l) just put l to return the value of l from the function. (Do not put return(l) as the effect of return is actually somewhat different from other languages.)
I also recommend copying the list before sorting it, so that you don't modify the original list. Try l : copy(l) before anything else.
As a complement of Robert Dodier's answer, some more words for explaining what is happening. Maxima has a functional language with following features:
last term in a block is also the value "returned" by this block;
print has to be taken as a function rather than a mere statement.
These two ideas explain what happend in your case:
the print(l) in your code performs something on your screen but also is an expression evaluating to l (try for instance something like a:print(5)$ which will print the number 5 but also assign the value 5 to the variable a;
since print(l) is also the last term in your block, your block will evaluate to l.
Thus your code prints l and also "return" it.
I found the problem. Instead of print(l) I should use append(l).

How to display specific unsat constraint, not whole core (Z3, Python)

How i can list only specific constraint result from my unsat core? I have a lot of conditions and printing whole core doesn't print all. I read that it can be done with assert_and_track and unsat_core commands. I found some examples but they don't works. Any experience with this?
s.assert_and_track(A > B, 'p1')
s.assert_and_track(B > C, 'p2')
if s.check() == sat:
print('ok')
else:
c = s.unsat_core
print(c) <- this print all core
So how to print only p1 or p2 (just true/false result) ? e.g. p2 = false, or it can be displayed in way as is displayed in print(c) mode - but just for p1.
The easiest way to achieve that is to simply save a map of labels to constraints, for this examples we can do
M = {}
M['p1'] = (A > B)
M['p2'] = (B > C)
M['p3'] = (C > A)
so that later we can print the core in terms of those constraints, for instance as follows
core = s.unsat_core()
for e in core:
print(M[str(e)])
Of course this will also work if you want to print only some entries instead of all of them.

Z3py SMT coding following variables and the formulas

I am really new to Z3 and SMT solvers.
I have the following problem which I don't know how to code in Z3py.
In the above diagram N is set of nodes, thus N = {Node1, Node2, Node3, Node4, Node5, Node6, Node7}
I is set of Inputs, I = {I1, I2, I3, I4}
O is set of Outputs, O = {O1, O2, O3}
G is a group where for any consecutive 2 outputs (Oi, Oj), if Oi is first output generated and Oj is second output generated then, Gk is set of nodes that were scheduled after the generation of Oi and before the generation of Oj, but if Oj was generated before Oi then Gk contains all the blocks that were scheduled before Oj was generated.
The scheduling of the nodes is given by another program.
For example in the above block diagram the scheduling of nodes along with generation of output is as follows:
First node scheduled = Node1
Second node scheduled = Node2
Third node scheduled = Node5
Output generated = O1
Fourth node scheduled = Node3
Fifth node scheduled = Node6
Output generated = O2
Sixth node scheduled = Node4
Fifth node scheduled = Node7
Output generated = O3
Thus from above we can say that G1 for (O1, O2) is = {Node3, Node6}
But G2 for (O2, O1) is = {Node1, Node2, Node5}
To execute each node we need a task, a task can implement 1 node or a set of nodes at a time.
Noder,i denotes ith node in group Gr.
Taskr,m denotes mth task in group Gr.
The boolean variables (can either be 0 or 1) :
fNoder,iTaskr,m represents if
Noder,i is mapped to Taskr,m
DNNoder,iNodes,j represents if
Nodes,j depends on Noder,i i.e. if there is a path from Noder,i to Nodes,j
DTTaskr,mTasks,n represents if
Tasks,n depends on Taskr,m
MTaskr,m represents if there is any node mapped on to Taskr,m
Based on the above information I have to formulate the following equations in SMT.
Minimize ( Σr,m
MTaskr,m )
MTaskr,m >=
fNoder,iTaskr,m (for all i)
Σm
fNoder,iTaskr,m = 1 (for all r != I,O)
example: fNoder,iTaskr,m + fNoder,iTaskr,m+1 + fNoder,iTaskr,m+2 = 1 + 0 + 0 = This tells us that Noder,i is mapped to Taskr,m since fNoder,iTaskr,m = 1 (only one node can be mapped to 1 task at a time but a task can be mapped to several nodes at a time)
fNoder,iTasks,m = 0 (for all r != s)
fNoder,iTaskr,m = 1 (for all r = I,O and m = i)
fNoder,iTaskr,m = 0 (for all r = I,O and m != i)
DTTaskr,mTasks,n >= fNoder,iTaskr,m + fNodes,jTasks,n + DNNoder,iNodes,j - 2
DTTaskr,mTasks,n >= DTTaskr,mTaskt,l + DTTaskt,lTasks,n - 1
DTTaskr,mTasks,n + DTTasks,nTaskr,m <= 1
I don't understand how to represent the variables and these formulas in SMT format.
I am not sure how to best answer because the question contains a lot of references to specifics that are not fully specified.
For example, what is I, and O?
You probably are asking how to add a system of linear inequalities. Or how to specify problems with integer variables that can be either 0 or 1.
One approach is to introduce functions as follows:
a = Function('a', IntSort(), IntSort(), IntSort())
Then 'a' is a function that maps pairs of integers to an integer.
You can declare function 'n' in a similar way (but I guess your example actually has some typos and you use n both as a function and as an index variable).
You can declare functions f, h, q in similar ways too.
Then in python you can write:
N = 5
s = Solver() # create a solver context
for r in range(N):
for i in range(N):
for m in range(N):
if m != i:
s.add(f(n(r,i),a(r,m)) == 0)
This adds the equality constraints on f that you specified.
The other equality and inequality constraints can be added in similar ways.
In the end you ask whether the resulting state is satisfiable.
print s.check()
print s.model() # print model for satisfiable outcome.
Other approaches are that you declare distinct constants for the different
versions of f. After all your suggested problem indicates that you are just
writing down a large system of inequalities over variables created in different
ways.
E.g., you can create and the constant v:
v = Const('f(a[%d][%d],a[%d][%d])' % (r,m,r,i), IntSort())
instead of the function application.

Why maxima cannot solve these equations

I have several equations that specify relationships between elements of an ellipse (minor and major semi axis, eccentricity, pericenter and apocenter distance, focal parameter).
I want to find other formulas that express each of those elements through combinations of all other elements. solve() works perfectly fine on some combinations, but not the other.
What is the difference between those cases and how I can make it solve?
sys:[b=a*sqrt(1-e^2),p=a*(1-e^2),c=a*(1+e),d=a*(1-e)];
solve(sys,[a,b,e,p]);
solve(sys,[a,b,e,c]);
solve(sys,[a,b,e,d]);
solve(sys,[a,b,p,c]);
solve(sys,[a,b,p,d]);
solve(sys,[a,b,c,d]);
/* solve(sys,[a,e,p,c]); -- gives error */
/* solve(sys,[a,e,p,d]); -- gives error */
/* solve(sys,[a,e,c,d]); -- gives error */
solve(sys,[a,p,c,d]);
solve(sys,[b,e,p,c]);
solve(sys,[b,e,p,d]);
solve(sys,[b,e,c,d]);
solve(sys,[b,p,c,d]);
solve(sys,[e,p,c,d]);
Here is output for "good" and "bad" case:
(%i5) solve(sys,[a,b,c,d]);
2
p sqrt(1 - e ) p p p
(%o5) [[a = - ------, b = - --------------, c = - -----, d = -----]]
2 2 e - 1 e + 1
e - 1 e - 1
(%i6) solve(sys,[a,e,p,c]);
algsys: tried and failed to reduce system to a polynomial in one variable; give up.
-- an error. To debug this try: debugmode(true);
Try to_poly_solve on these. It is a share package -- you have to enter load(to_poly_solve); before calling it.

Resources