can any one here help me to make prolog clauses inside python using pyswip like this
database:
man(peter).
woman(adam).
man(jonathan).
man(paul).
woman(cloe).
father(jonathan, peter).
father(pierre, adam).
brother(pierre, paul).
father(pierre, cloe).
these are functions
child(X, Y) :- father(Y,X).
son(X, Y) :- man(X) , father(Y, X).
daughter(X, Y) :- woman(X), father(Y, X).
brother(X, Y) :- man(X), father(Z, Y), father(Z, X).
sister(X, Y) :- woman(X), father(Z, Y), father(Z, X).
how can i define these prolog functions inside python through pyswip
I don't have time to make a detailed answer right now, I'll update it latter but here's a simple example of an interface in python I had done to a prolog program that played reversi.
#!/usr/bin/python
import sys
from pyswip import Prolog, Functor, Variable, Query
prolog = Prolog()
prolog.consult('./reversi_game.pl')
prolog.consult('./alphabeta.pl')
start_board = Functor("startBoard", 1)
b = Variable()
start_board_query = Query(start_board(b))
start_board_query.nextSolution()
print()
print_board(list(b.get_value())) # an 8*8 grid filled with 0 except at the 4 center squares that have x's and o's
start_board_query.closeQuery()
set_to_x = Functor("setToX", 1)
xp = Variable()
set_player_query = Query(set_to_x(xp))
set_player_query.nextSolution()
x_player = xp.get_value()
print()
print(x_player) # 'x'
set_player_query.closeQuery()
So what it is going on here? To define the predicate interface you create a Functor, giving it a string which is the name of the predicate in Prolog and its arity, you create as many variables as you need and pass them to your Functor creating a Query from it.
You can then proceed calling nextSolution() on the Query object for as long as you want depending on how many solutions you need, if I remember correctly the result will be None when it fails and it stops giving any solutions. Then use the get_value() function to extract the values of the variables of your predicate.
You can also check this out:
https://github.com/yuce/pyswip/tree/master/examples
Hope it helps.
EDITED:
I know this "promised a bit more detailed answer" is a bit late now, but anyways.
Related
For my current assignment, I am to establish the stability of intersection/equilibrium points between two nullclines, which I have defined as follows:
def fNullcline(F):
P = (1/k)*((1/beta)*np.log(F/(1-F))-c*F+v)
return P
def pNullcline(P):
F = (1/delta)*(pD-alpha*P+(r*P**2)/(m**2+P**2))
return F
I also have a method "stability" that applies the Hurwitz criteria on the underlying system's Jacobian:
def dPdt(P,F):
return pD-delta*F-alpha*P+(r*P**2)/(m**2+P**2)
def dFdt(P,F):
return s*(1/(1+sym.exp(-beta*(-v+c*F+k*P)))-F)
def stability(P,F):
x = sym.Symbol('x')
ax = sym.diff(dPdt(x, F),x)
ddx = sym.lambdify(x, ax)
a = ddx(P)
# shortening the code here: the same happens for b, c, d
matrix = [[a, b],[c,d]]
eigenvalues, eigenvectors = np.linalg.eig(matrix)
e1 = eigenvalues[0]
e2 = eigenvalues[1]
if(e1 >= 0 or e2 >= 0):
return 0
else:
return 1
The solution I was looking for was later provided. Basically, values became too small! So this code was added to make sure no too small values are being used for checking the stability:
set={0}
for j in range(1,210):
for i in range(1,410):
x=i*0.005
y=j*0.005
x,y=fsolve(System,[x,y])
nexist=1
for i in set:
if(abs(y-i))<0.00001:
nexist=0
if(nexist):
set.add(y)
set.discard(0)
I'm still pretty new to coding so the function in and on itself is still a bit of a mystery to me, but it eventually helped in making the little program run smoothly :) I would again like to express gratitude for all the help I have received on this question. Below, there are still some helpful comments, which is why I will leave this question up in case anyone might run into this problem in the future, and can find a solution thanks to this thread.
After a bit of back and forth, I came to realise that to avoid the log to use unwanted values, I can instead define set as an array:
set = np.arange(0, 2, 0.001)
I get a list of values within this array as output, complete with their according stabilities. This is not a perfect solution as I still get runtime errors (in fact, I now get... three error messages), but I got what I wanted out of it, so I'm counting that as a win?
Edit: I am further elaborating on this in the original post to improve the documentation, however, I would like to point out again here that this solution does not seem to be working, after all. I was too hasty! I apologise for the confusion. It's a very rocky road for me. The correct solution has since been provided, and is documented in the original question.
I am using sympy to help automate the process of finding equations of motion for some systems using the Euler Lagrange method. What would really make this easy is if I could define a function q and specify its time derivative qd --> d/dt(q) = qd. Likewise I'd like to specify d/dt(qd) = qdd. This is helpful because as part of the process of finding the equations of motion, I need to take derivatives (with respect to time, q, and qd) of expressions that are functions of q and qd. In the end I'll end up with an equation in terms of q, qd, and qdd and I'd like to be able to either print this neatly or use lambdify to convert this to a neat numpy function for use in a simulation.
Currently I've accomplished this is a very roundabout and annoying way by defining q as a function and qd as the derivative of that function:
q = sympy.Function('q', real=True)(t)
q_diff = diff(q,t)
This is fine for most of the process but then I end up with a messy expression filled with "Derivative (q, t)" and "Derivative (Derivative(q, t), t)" which is hard to wrangle into a neat printing format and difficult to turn into a numpy function using lambdify. My current solution is thus to use the subs function and replace q_diff and diff(q_diff, t) with sympy symbols qd and qdd respectively, which cleans things up and makes manipulating the expression much easier. This seems like a bad hack though and takes tons of time to do for more complicated equations with lots of state variables.
What I'd like is to define a function, q, with a specific value for the time derivative. I'd pass in that value when creating the function, and sympy could treat it like a generic Function object but would use whatever I'd given it for the time derivative instead of just saying "Derivative(q, t)". I'd like something like this:
qdd = sympy.symbols('qdd')
qd = my_func(name='qd', time_deriv=qdd)
q = my_func(name='q', time_deriv=qd)
diff(q, t)
>>> qd
diff(q**2, t)
>>> 2*q*qd
diff(diff(q**2, t))
>>> 2*q*qdd + 2*qd**2
expr = q*qd**2
expr.subs(q, 5)
>>> 5*qd**2
Something like that, where I could still use the subs command and lambdify command to substitute numeric values for q and qd, would be extremely helpful. I've been trying to do this but I don't understand enough of how the base sympy.Function class works to get this going. This is what I have right now:
class func(sp.Function):
def __init__(self, name, deriv):
self.deriv = deriv
self.name = name
def diff(self, *args, **kwargs):
return self.deriv
def fdiff(self, argindex=1):
assert argindex == 1
return self.deriv
This code so far does not really work, I don't know how to specify that specifically the time derivative of q is qd. Right now all derivatives of q are returning q?
I don't know if this is just a really bad solution, if I should be avoiding this issue entirely, or if there's already a clean way to solve this. Any advice would be very appreciated.
I'm in the middle of a big (and frankly quite hard) project so while this is my first interrogation, it probably won't be the last. Also : english is not my first langage so 'Sorry for bad english' and I'm writing this on my phone so 'Sorry for bad formating'.
Ok so : I'm trying to implement the General Number Field Sieve in Python, and I'm, at least for now, heavily relying on sympy.
Here is a peice of code where I'm struggling. In the code below, gpc(N,m) is a float list.
From sympy import Poly
From sympy.abc import x
g = Poly(gpc(N,m), x) [*]
However, when I do that, I get a polynomial over the domain RR and I would very much like to switch this to another domain D (where D will end up being ZZ['x'] but I would like this function to be general)
I'm aware of the fact that I can slightly modify [*] in
g = Poly(gpc(N,m), x, domain = D)
to get what I want. However, this wouldn't be enough. Somewhere else in my code, I need to be able to change the domain of an already constructed polynomial, and this solution wouldn't help.
When I lookep it up, I found the change_ring method so I tried this :
f = g.change_ring(D)
However, upon execution, I get the error message :
'Poly' object has no attribute 'change_ring'
So I guess that this function don't exist.
Does anyone knows how to change the domain of a polynomial ?
Thanks a lot !
It looks like creating a new Poly instance is the best approach; there are a few class methods that could help (take a look at the Poly.from_* class methods)
For example:
from sympy import Poly
from sympy.abc import x, a
g = Poly(x**3 + a*x*2 - 5*x + 6, x)
print(g) # Poly(x**3 + (2*a - 5)*x + 6, x, domain='ZZ[a]')
f = Poly.from_poly(g, *g.gens, domain='ZZ[a, b]')
print(f) # Poly(x**3 + (2*a - 5)*x + 6, x, domain='ZZ[a,b]')
I also wonder if rationalizing your floats at some point might help - see e.g. nsimplify.
I'm trying to divide up my SConstruct file into blocks of code, where each block
is controlled by an Alias, and no code is run by default; i.e. just by runningscons.
The Aliases are of course run from the command line e.g. (in the example below):
scons h
Here is some example code. This appears to work Ok. However, three questions.
Is there a better way to do this?
More specifically, I don't understand how the target arguments in the Alias call
get passed to the h and h3 action functions. I notice if I leave them blank the
build does not work. However there is no obvious way for the targets to be passed
to these functions, since they do not take any arguments.
Relatedly, the documentation says that action functions requires target, source,
and env arguments. These action functions don't have these but work anyway. How come?
Code follows:
#!/usr/bin/python
Default(None)
def h(env):
x = env.Program("hello1", "hello1.c")
y = env.Program("hello2", "hello2.c")
return 0
def h3(env):
y = env.Program("hello3", "hello3.c")
return 0
env = Environment()
env.AddMethod(h, "HELLO")
env.AddMethod(h3, "HELLO3")
env.Alias("h", ["hello1", "hello2"], env.HELLO())
env.Alias("h3", ["hello3"],env.HELLO3())
To answer your first question: yes, there is a better way.
env = Environment()
# h:
x = env.Program("hello1", "hello1.c")
y = env.Program("hello2", "hello2.c")
env.Alias("h", [x,y])
# equivalently: env.alias("h", ["hello1", "hello2"])
# h3
y = env.Program("hello3", "hello3.c")
env.Alias("h3", y)
Default(None)
Alternatively, if you like grouping your Program() calls in a subroutine, that's okay, too. You just don't need AddMethod() for what you're doing:
env = Environment()
def h(env):
x = env.Program("hello1", "hello1.c")
y = env.Program("hello2", "hello2.c")
return x,y
def h3(env):
return env.Program("hello3", "hello3.c")
env.Alias("h", h(env))
env.Alias("h3", h3(env))
Default(None)
I am new to SymPy and Python in general, and I am currently working with Python 2.7 and SymPy 0.7.5 with the objective to:
a) read a system of differential equations from a text file
b) solve the system
I already read this question and this other question, and they are almost what I am looking for, but I have an additional issue: I do not know in advance the form of the system of equations, so I cannot create the corresponding function using def inside the script, as in this example. The whole thing has to be managed at run-time.
So, here are some snippets of my code. Suppose I have a text file system.txt containing the following:
dx/dt = 0.0387*x - 0.0005*x*y
dy/dt = 0.0036*x*y - 0.1898*y
What I do is:
# imports
import sympy
import scipy
import re as regex
# define all symbols I am going to use
x = sympy.Symbol('x')
y = sympy.Symbol('y')
t = sympy.Symbol('t')
# read the file
systemOfEquations = []
with open("system.txt", "r") as fp :
for line in fp :
pattern = regex.compile(r'.+?\s+=\s+(.+?)$')
expressionString = regex.search(pattern, line) # first match ends in group(1)
systemOfEquations.append( sympy.sympify( expressionString.group(1) ) )
At this point, I am stuck with the two symbolic expressions inside the systemOfEquation list. Provided that I can read the initial conditions for the ODE system from another file, in order to use scipy.integrate.odeint, I would have to convert the system into a Python-readable function, something like:
def dX_dt(X, t=0):
return array([ 0.0387*X[0] - 0.0005*X[0]*X[1] ,
-0.1898*X[1] + 0.0036*X[0]*X[1] ])
Is there a nice way to create this at run-time? For example, write the function to another file and then import the newly created file as a function? (maybe I am being stupid here, but remember that I am relatively new to Python :-D)
I've seen that with sympy.utilities.lambdify.lambdify it's possible to convert a symbolic expression into a lambda function, but I wonder if this can help me...lambdify seems to work with one expression at the time, not with systems.
Thank you in advance for any advice :-)
EDIT:
With minimal modifications, Warren's answer worked flawlessly. I have a list of all symbols inside listOfSymbols; moreover, they appear in the same order as the columns of data X that will be used by odeint. So, the function I used is
def dX_dt(X, t):
vals = dict()
for index, s in enumerate(listOfSymbols) :
if s != time :
vals[s] = X[index]
vals[time] = t
return [eq.evalf(subs=vals) for eq in systemOfEquations]
I just make an exception for the variable 'time' in my specific problem. Thanks again! :-)
If you are going to solve the system in the same script that reads the file (so systemOfEquations is available as a global variable), and if the only variables used in systemOfEquations are x, y and possibly t, you could define dX_dt in the same file like this:
def dX_dt(X, t):
vals = dict(x=X[0], y=X[1], t=t)
return [eq.evalf(subs=vals) for eq in systemOfEquations]
dX_dt can be used in odeint. In the following ipython session, I have already run the script that creates systemOfEquations and defines dX_dt:
In [31]: odeint(dX_dt, [1,2], np.linspace(0, 1, 5))
Out[31]:
array([[ 1. , 2. ],
[ 1.00947534, 1.90904183],
[ 1.01905178, 1.82223595],
[ 1.02872997, 1.73939226],
[ 1.03851059, 1.66032942]]