SlideShare a Scribd company logo
Conrad Calmez
Christoph Matthies
Robert Lehmann
Pybelsberg
© 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030
1
a = pt(100, 100)
b = pt(200, 200)
always {
a.dist(b) == 200
}
a.setX(50)
a.dist(b) # => 200
babelsberg-js
© 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030
https://github.com/timfel/babelsberg-js
2
a = pt(100, 100)
b = pt(200, 200)
always {
a.dist(b) == 200
}
a.setX(50)
a.dist(b) # => 200
© 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030
babelsberg-js
3
a = Point(100, 100)
b = Point(200, 200)
@always
def constraint():
return a.dist(b) == 200
a.x = 50
a.dist(b) # => 200
pybelsberg
© 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030
4
100
200
100
200
141.42
a
b
5
p = Problem()
p.a_x = p.a_y = 100; p.b_x = p.b_y = 200
constraint = …
p.always(constraint)
print(dist((p.a_x, p.a_y), (p.b_x, p.b_y)))
# => 200
Boilerplate
6
p = Problem()
p.a_x = p.a_y = 100; p.b_x = p.b_y = 200
constraint = …
p.always(constraint)
print(dist((p.a_x, p.a_y), (p.b_x, p.b_y)))
# => 200
Boilerplate
?
7
100
200
100
200
a.x
f(a.x) = √(a.x−b.x)² + (a.y−b.y)²
8
a
b
100
200
100
200
a.x
f(a.x) = √(a.x−b.x)² + (a.y−b.y)²
f(a.x) = 200
9
a
b
100
200
100
200
a.x
f(a.x) = √(a.x−b.x)² + (a.y−b.y)²
f(a.x) = 200
f
10
a
b
100
200
100
200
a.x
f(a.x) = √(a.x−b.x)² + (a.y−b.y)²
f(a.x) = 200
g(a.x) = f(a.x) − 200 = 0
11
a
b
100
200
100
200
a.x
200
26.79
12
a
b
def constraint(a_x, a_y, b_x, b_y):
return dist((a_x, a_y), (b_x, b_y)) — 200
1
Defining the constraint
actually: f(a.x, a.y, b.x, b.y) = √(a.x−b.x)² + (a.y−b.y)²
13
Satisfying constraints
● Finding values to satisfy constraints is
solving equations.
● Solving equations means finding the
root of polynomials.
dist((a_x, a_y), (b_x, b_y)) — 200)
14
def constraint(a_x, a_y, b_x, b_y):
return dist((a_x, a_y), (b_x, b_y)) — 200
def constraint(a_x, a_y, b_x, b_y):
return dist((a_x, a_y), (b_x, b_y)) == 200
2
Define constraints naturally
15
class Expr(object):
def __add__(self, other):
return Expr('+', self, other)
def __eq__(self, other):
return Expr('=', self, other)
…
def to_eval(self):
return self.left.to_eval() + self.operator 
+ self.right.to_eval()
Remember performed operations
16
def constraint(a_x, a_y, b_x, b_y):
return dist((a_x, a_y), (b_x, b_y)) == 200
3
No explicit declaration of parameters
17
def foo():
x
foo()
# => NameError: global name 'x' is not defined
Variables in functions
18
class Namespace(dict):
def __getattr__(self, key):
print("getattr", key)
def foo():
a + b
ns = Namespace()
proxy = types.FunctionType(foo.__code__, ns)
proxy()
# => ???
Execute function in different global scope
19
Execute function in different global scope
class Namespace(dict):
def __getattr__(self, key):
print("getattr", key)
def foo():
a + b
ns = Namespace()
proxy = types.FunctionType(foo.__code__, ns)
proxy()
# => getattr a
# => getattr b
20
2.7.6
case LOAD_GLOBAL:
w = GETITEM(names, oparg);
x = PyDict_GetItem(f->f_globals, w);
PUSH(x);
3.3.5
TARGET(LOAD_GLOBAL)
w = GETITEM(names, oparg);
if (PyDict_CheckExact(f->f_globals)) {
…
} else {
/* Slow-path if globals or builtins is not a dict */
x = PyObject_GetItem(f->f_globals, w);
…
}
PUSH(x);
CPython: Python/ceval.c
21
def constraint():
return dist((a_x, a_y), (b_x, b_y)) == 200
a_x = 50
print(a_x, a_y, b_x, b_y)
# => 50 100 200 -32.14
print(dist(a_x, a_y), (b_x, b_y)))
# => 200
4
Work with global variables
22
TARGET(STORE_FAST)
v = POP();
// SETLOCAL(oparg, v);
PyObject *tmp = fastlocals[i];
fastlocals[i] = value;
Py_XDECREF(tmp);
FAST_DISPATCH();
CPython: Python/ceval.c
no Python protocol is used -- GAME OVER
23
class Namespace(dict):
def __setattr__(self, key):
print("setattr", key)
def foo():
global a
a = 2
ns = Namespace()
proxy = types.FunctionType(foo.__code__, ns)
proxy()
# => no output ☹
Function globals can be overridden?
24
TARGET(STORE_GLOBAL) {
PyObject *name = GETITEM(names, oparg);
PyObject *v = POP();
int err;
err = PyDict_SetItem(f->f_globals, name, v);
Py_DECREF(v);
if (err != 0)
goto error;
DISPATCH();
}
GAME OVER -- bug, see ticket #1402289
CPython: Python/ceval.c
25
class in_constrained(constraint):
a_x = 50
Use class as scope
26
class Namespace(dict):
def __setitem__(self, key, val):
print("setitem", key, val)
class Meta(type):
def __prepare__(self, obj):
return Namespace()
class Object(metaclass=Meta):
x = 2
# => setitem __module__ __main__
# => setitem __qualname__ Object
# => setitem x 2
Use class as scope
27
class Namespace(dict):
def __setitem__(self, key, val):
print("setitem", key, val)
class Meta(type):
def __prepare__(self, obj):
return Namespace()
class Object(metaclass=Meta):
x = 2
# => setitem __module__ __main__
# => setitem __qualname__ Object
# => setitem x 2
Use class as scope
Stamp © 2012 Stuart Miles, FreeDigitalPhotos.net, http://www.freedigitalphotos.net/images/Other_Metaphors_and__g307-Reject_Stamp_p86053.html
28
a = Point(100, 100)
b = Point(200, 200)
@always
def point_distance_constraint():
return a.dist(b) == 200
a.x = 50
# a.__setattr__('x', 50) ~› solve()
a.dist(b) # => 200
5
Catch instance variables
29
class A(object):
pass
def setattr(self, name, value):
print("setattr", name, value)
a = A()
a.__setattr__ = setattr
a.x = 10
# no output ☹
Notice instance variable assignment
30
3.3.5
int PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value)
{
PyTypeObject *tp = Py_TYPE(v);
int err;
Py_INCREF(name);
if (tp->tp_setattr != NULL) {
err = (*tp->tp_setattr)(v, name_str, value);
Py_DECREF(name);
return err;
}
…
return -1;
}
CPython: Objects/object.
c
31
class A(object):
pass
def setattr(self, name, value):
print("setattr", name, value)
a = A()
type(a).__setattr__ = setattr
a.x = 10
# => setattr x 10
Use type
32
always:
a.dist(b) == 200
6
Source code transforms
33
import codecs
def decode(text):
return u'x=5n' + text.decode('utf8')
codecs.register('babelsberg', decode)
# encoding: babelsberg
print(x) # => 5
Custom encoding
*
* not the actual codecs API 34
## main.py ☹
import custom_codec
import demo
## demo.py
# encoding: babelsberg
print(x) # => 5
Custom encoding, caveat
depends on
35
## main.py ☹
import custom_codec
import demo
## demo.py
# encoding: babelsberg
print(x) # => 5
Custom encoding, caveat
36
<demo>
a = Point(100.0, 100.0)
b = Point(200.0, 200.0)
@always
def constant_distance():
yield a.distance(b) == 200
assert_almost_equals(a.distance(b), 200)
a.x = 50
assert_almost_equals(a.distance(b), 200)
37
0 LOAD_GLOBAL 0 (a)
3 LOAD_ATTR 1 (dist)
6 LOAD_GLOBAL 2 (b)
9 CALL_FUNCTION 1
12 LOAD_CONST 1 (200)
15 COMPARE_OP 2 (==)
18 POP_TOP
19 LOAD_CONST 0 (None)
22 RETURN_VALUE
a = Point(100, 100)
b = Point(200, 200)
@always
def constant_distance():
a.dist(b) == 200
patch(obj):
for each instance variable of obj:
remember original value
replace with wrapped valuea.x, a.y, b.x, b.y
38
constraint = constant_distance()
for all remembered instance variables:
solver.add(instance_variable == value)
solver.add(constraint)
solver.solve()
(= 200 (sqrt
(+
(**
(- a.x b.x)
2)
(**
(- a.y b.y)
2)
)))
39
pybelsberg.py
Python
Theorem Solver
?
40
SciPy
41
scipy.optimize.fsolve(
func, #A function that takes at least one argument.
x0, #The starting estimate for the roots of func(x) = 0.
args=(), #Any extra arguments to func.
fprime=None, #A function to compute the Jacobian of func with derivatives across the rows.
By default, the Jacobian will be estimated.
full_output=0, #If True, return optional outputs.
col_deriv=0, #Specify whether the Jacobian function computes derivatives down the columns
(faster, because there is no transpose operation).
xtol=1.49012e-08, #The calculation will terminate if the relative error between two
consecutive iterates is at most xtol
maxfev=0, #The maximum number of calls to the function. If zero, then 100*(N+1) is the maximum
where N is the number of elements in x0.
band=None, #If set to a two-sequence containing the number of sub- and super-diagonals within
the band of the Jacobi matrix, the Jacobi matrix is considered banded (only for fprime=None).
epsfcn=None, #A suitable step length for the forward-difference approximation of the
Jacobian (for fprime=None). If epsfcn is less than the machine precision, it is assumed that the relative
errors in the functions are of the order of the machine precision.
42
scipy.optimize.fsolve
constraint = lambda args: [
math.sqrt(
(args[0]-args[1])**2
+ (args[2]-args[3])**2
) - 200
]*4
fsolve(constraint, [1, 1, 1, 1])
# => (array([ 201., 1., 1., 1.])
starting values
43
scipy.optimize.fsolve
● Requires transformation
○ “Return the roots of the (non-linear) equations defined by
func(x) = 0”
○ Cannot access instance variables
○ Function value must be closer to 0 if the parameters are
closer to the solution
○ x = y → x - y = 0 x > y → x - y if x - y > 0 else 0
● Requires starting estimate
○ Hard to determine best value for user-defined equations
44
Z3
45
Z3 theorem prover
● Developed by Microsoft Research http://z3.codeplex.com/
● General-purpose solver (not only for finding roots)
● Many built-in theories
○ linear arithmetic, nonlinear arithmetic, bitvectors, arrays,
datatypes, quantifiers
● Python bindings
○ already does ASTs
46
from z3 import *
a_x, a_y = Real('a.x'), Real('a.y')
b_x, b_y = Real('b.x'), Real('b.y')
s = Solver()
s.add(a_x == 100, …)
s.add(sqrt((a_x-b_x)**2 + (a_y-b_y)**2) == 200)
print(s.check()) # => sat
print(s.model()) # => [a.x = 26.79, a.y = 100, …]
Z3 theorem prover
47
Z3 theorem prover
● Quality of life improvement
○ Try to minimize the amount of variables that are
changed by the solver due to a constraint
48
Add all constraints
● Put a rollback point (“push” in Z3 lingo)
● Add all current variables (eg. from Point constructor, example
a = Point(50, 100)) as “soft constraints”
○ ie., boolnew
→ a.x = 50
● Solver tells us which implications are wrong (were
invalidated to satisfy constraints)
● We remove these from future runs, so that these variables
are preferably modified
Z3 theorem prover
49
s.add(sqrt((a.x - b.x)**2 … == 200)
s.push()
s.add(a.x == 100, a.y == 100, b.x == 50, b.y == 50)
s.check() # => unsat, a.x
s.pop()
s.add(a.x == 100, a.y == 100, …)
s.check() # => sat
transaction
50
© 2008 by “GillyBerlin”, flickr.com/photos/gillyberlin/2531057541 (CC BY 2.0)
● Constraint-based programming with object-oriented
Python
● Leverage same advanced solver as Babelsberg/JS
● Quality of life improvements for the programmer
51

More Related Content

What's hot (20)

PDF
Introducción a Elixir
Svet Ivantchev
 
PDF
TensorFlow Tutorial
NamHyuk Ahn
 
PDF
Introduction to Python
UC San Diego
 
PDF
Implementing virtual machines in go & c 2018 redux
Eleanor McHugh
 
PDF
Beginners python cheat sheet - Basic knowledge
O T
 
KEY
Haskellで学ぶ関数型言語
ikdysfm
 
PDF
Google TensorFlow Tutorial
台灣資料科學年會
 
PPTX
Groovy vs Boilerplate and Ceremony Code
stasimus
 
PDF
Futures e abstração - QCon São Paulo 2015
Leonardo Borges
 
PDF
Python speleology
Andrés J. Díaz
 
PPTX
Python 내장 함수
용 최
 
PDF
Python decorators (中文)
Yiwei Chen
 
PDF
Optics with monocle - Modeling the part and the whole
Ilan Godik
 
PDF
PythonOOP
Veera Pendyala
 
PPTX
TensorFlow
jirimaterna
 
PDF
Gentlest Introduction to Tensorflow
Khor SoonHin
 
PDF
Internal workshop es6_2015
Miguel Ruiz Rodriguez
 
PDF
Python For Data Science Cheat Sheet
Karlijn Willems
 
PPT
Collection v3
Sunil OS
 
Introducción a Elixir
Svet Ivantchev
 
TensorFlow Tutorial
NamHyuk Ahn
 
Introduction to Python
UC San Diego
 
Implementing virtual machines in go & c 2018 redux
Eleanor McHugh
 
Beginners python cheat sheet - Basic knowledge
O T
 
Haskellで学ぶ関数型言語
ikdysfm
 
Google TensorFlow Tutorial
台灣資料科學年會
 
Groovy vs Boilerplate and Ceremony Code
stasimus
 
Futures e abstração - QCon São Paulo 2015
Leonardo Borges
 
Python speleology
Andrés J. Díaz
 
Python 내장 함수
용 최
 
Python decorators (中文)
Yiwei Chen
 
Optics with monocle - Modeling the part and the whole
Ilan Godik
 
PythonOOP
Veera Pendyala
 
TensorFlow
jirimaterna
 
Gentlest Introduction to Tensorflow
Khor SoonHin
 
Internal workshop es6_2015
Miguel Ruiz Rodriguez
 
Python For Data Science Cheat Sheet
Karlijn Willems
 
Collection v3
Sunil OS
 

Viewers also liked (18)

PDF
Frodsham 4 6-14
CJH47
 
PPTX
Gilchrist IC - AIMRADIAL 2013 - Outpatient in the US
International Chair on Interventional Cardiology and Transradial Approach
 
DOCX
Los navegadores más usados
marcejesus
 
PPT
You want to learn spanish
firststepargentina
 
PPTX
ELABORACIÓN DE UNA BANDERA
e1quimica
 
ODT
Articles technologies
barallor
 
PPTX
Creation & Nature
Academy for Christian Thought
 
DOCX
Narrativa dic
Jocelyn Nuñez Aguilar
 
PDF
3.BestImplementation
Karthikeyan Selvaraj
 
PDF
Secuencia didactica
PUBLICACION ENLINEA
 
PDF
¿Qué es un modelo de negocio?
Omar Vite
 
PPTX
Transporte de sustancias a través de las membranas celulares
Mi Pediatra
 
PPSX
Charla Higiene Postural.
Ana C.C.
 
PPT
Spaulding C - AIMRADIAL 2013 - Heparin and radial
International Chair on Interventional Cardiology and Transradial Approach
 
PDF
“Getting to Yes” - Principled Negotiation
Floris Barthel
 
Frodsham 4 6-14
CJH47
 
Gilchrist IC - AIMRADIAL 2013 - Outpatient in the US
International Chair on Interventional Cardiology and Transradial Approach
 
Los navegadores más usados
marcejesus
 
You want to learn spanish
firststepargentina
 
ELABORACIÓN DE UNA BANDERA
e1quimica
 
Articles technologies
barallor
 
Narrativa dic
Jocelyn Nuñez Aguilar
 
3.BestImplementation
Karthikeyan Selvaraj
 
Secuencia didactica
PUBLICACION ENLINEA
 
¿Qué es un modelo de negocio?
Omar Vite
 
Transporte de sustancias a través de las membranas celulares
Mi Pediatra
 
Charla Higiene Postural.
Ana C.C.
 
Spaulding C - AIMRADIAL 2013 - Heparin and radial
International Chair on Interventional Cardiology and Transradial Approach
 
“Getting to Yes” - Principled Negotiation
Floris Barthel
 
Ad

Similar to Pybelsberg — Constraint-based Programming in Python (20)

PPT
Convex Optimization Modelling with CVXOPT
andrewmart11
 
PPTX
Module 4.pptx
charancherry185493
 
PDF
lpSolve - R Library
David Faris
 
PPTX
Lecture 6 python oop (ewurc)
Al-Mamun Riyadh (Mun)
 
PDF
Model Presolve, Warmstart and Conflict Refining in CP Optimizer
Philippe Laborie
 
PDF
Investigating Python Wats
Amy Hanlon
 
PDF
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Dr. Volkan OBAN
 
PPTX
Computation Using Scipy, Scikit Image, Scikit Learn
Prabu U
 
PDF
Module 4.pdf
VijayKumar886687
 
PPTX
Optimization tutorial
Northwestern University
 
PDF
Dafunctor
Buganini Chiu
 
PDF
Accelerating Key Bioinformatics Tasks 100-fold by Improving Memory Access
Igor Sfiligoi
 
PDF
Python course slides topic objects in python
MuhammadIfitikhar
 
PDF
numpy.pdf
ssuser457188
 
PDF
Write Python for Speed
Yung-Yu Chen
 
PDF
Probabilistic Accuracy Bounds @ Papers We Love SF
Aysylu Greenberg
 
PDF
E10
lksoo
 
PDF
Numpy questions with answers and practice
basicinfohub67
 
PDF
MSc Thesis_Francisco Franco_A New Interpolation Approach for Linearly Constra...
Francisco Javier Franco Espinoza
 
PPT
Least Square Optimization and Sparse-Linear Solver
Ji-yong Kwon
 
Convex Optimization Modelling with CVXOPT
andrewmart11
 
Module 4.pptx
charancherry185493
 
lpSolve - R Library
David Faris
 
Lecture 6 python oop (ewurc)
Al-Mamun Riyadh (Mun)
 
Model Presolve, Warmstart and Conflict Refining in CP Optimizer
Philippe Laborie
 
Investigating Python Wats
Amy Hanlon
 
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Dr. Volkan OBAN
 
Computation Using Scipy, Scikit Image, Scikit Learn
Prabu U
 
Module 4.pdf
VijayKumar886687
 
Optimization tutorial
Northwestern University
 
Dafunctor
Buganini Chiu
 
Accelerating Key Bioinformatics Tasks 100-fold by Improving Memory Access
Igor Sfiligoi
 
Python course slides topic objects in python
MuhammadIfitikhar
 
numpy.pdf
ssuser457188
 
Write Python for Speed
Yung-Yu Chen
 
Probabilistic Accuracy Bounds @ Papers We Love SF
Aysylu Greenberg
 
E10
lksoo
 
Numpy questions with answers and practice
basicinfohub67
 
MSc Thesis_Francisco Franco_A New Interpolation Approach for Linearly Constra...
Francisco Javier Franco Espinoza
 
Least Square Optimization and Sparse-Linear Solver
Ji-yong Kwon
 
Ad

More from Christoph Matthies (20)

PDF
Investigating Software Engineering Artifacts in DevOps Through the Lens of Bo...
Christoph Matthies
 
PDF
Automated Exercises & Software Development Data
Christoph Matthies
 
PDF
Challenges (and Opportunities!) of a Remote Agile Software Engineering Projec...
Christoph Matthies
 
PDF
Experience vs Data: A Case for More Data-informed Retrospective Activities
Christoph Matthies
 
PDF
More than Code: Contributions in Scrum Software Engineering Teams
Christoph Matthies
 
PDF
Agile Software Development Practices: Perceptions & Project Data
Christoph Matthies
 
PDF
The Road to Data-Informed Agile Development Processes
Christoph Matthies
 
PDF
Counteracting Agile Retrospective Problems with Retrospective Activities
Christoph Matthies
 
PDF
Using Data to Inform Decisions in Agile Software Development
Christoph Matthies
 
PDF
An Additional Set of (Automated) Eyes: Chatbots for Agile Retrospectives
Christoph Matthies
 
PDF
Feedback in Scrum: Data-Informed Retrospectives
Christoph Matthies
 
PDF
Beyond Surveys: Analyzing Software Development Artifacts to Assess Teaching E...
Christoph Matthies
 
PDF
Scrum2Kanban: Integrating Kanban and Scrum in a University Software Engineeri...
Christoph Matthies
 
PDF
Should I Bug You? Identifying Domain Experts in Software Projects Using Code...
Christoph Matthies
 
PDF
Introduction to Lean Software & Kanban
Christoph Matthies
 
PDF
Lightweight Collection and Storage of Software Repository Data with DataRover
Christoph Matthies
 
PDF
Git Tricks — git utilities that make life git easier
Christoph Matthies
 
PDF
How to reverse engineer Android applications—using a popular word game as an ...
Christoph Matthies
 
PDF
Beat Your Mom At Solitaire—Reverse Engineering of Computer Games
Christoph Matthies
 
PDF
Introduction to Homomorphic Encryption
Christoph Matthies
 
Investigating Software Engineering Artifacts in DevOps Through the Lens of Bo...
Christoph Matthies
 
Automated Exercises & Software Development Data
Christoph Matthies
 
Challenges (and Opportunities!) of a Remote Agile Software Engineering Projec...
Christoph Matthies
 
Experience vs Data: A Case for More Data-informed Retrospective Activities
Christoph Matthies
 
More than Code: Contributions in Scrum Software Engineering Teams
Christoph Matthies
 
Agile Software Development Practices: Perceptions & Project Data
Christoph Matthies
 
The Road to Data-Informed Agile Development Processes
Christoph Matthies
 
Counteracting Agile Retrospective Problems with Retrospective Activities
Christoph Matthies
 
Using Data to Inform Decisions in Agile Software Development
Christoph Matthies
 
An Additional Set of (Automated) Eyes: Chatbots for Agile Retrospectives
Christoph Matthies
 
Feedback in Scrum: Data-Informed Retrospectives
Christoph Matthies
 
Beyond Surveys: Analyzing Software Development Artifacts to Assess Teaching E...
Christoph Matthies
 
Scrum2Kanban: Integrating Kanban and Scrum in a University Software Engineeri...
Christoph Matthies
 
Should I Bug You? Identifying Domain Experts in Software Projects Using Code...
Christoph Matthies
 
Introduction to Lean Software & Kanban
Christoph Matthies
 
Lightweight Collection and Storage of Software Repository Data with DataRover
Christoph Matthies
 
Git Tricks — git utilities that make life git easier
Christoph Matthies
 
How to reverse engineer Android applications—using a popular word game as an ...
Christoph Matthies
 
Beat Your Mom At Solitaire—Reverse Engineering of Computer Games
Christoph Matthies
 
Introduction to Homomorphic Encryption
Christoph Matthies
 

Recently uploaded (20)

PDF
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
PDF
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
PDF
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
PPTX
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
PDF
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
PDF
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PDF
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
PDF
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
PPTX
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PDF
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
PPTX
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
PPTX
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
PPTX
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
PDF
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PDF
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
PPTX
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 
NEW-Viral>Wondershare Filmora 14.5.18.12900 Crack Free
sherryg1122g
 
The 5 Reasons for IT Maintenance - Arna Softech
Arna Softech
 
Automate Cybersecurity Tasks with Python
VICTOR MAESTRE RAMIREZ
 
Hardware(Central Processing Unit ) CU and ALU
RizwanaKalsoom2
 
Top Agile Project Management Tools for Teams in 2025
Orangescrum
 
MiniTool Partition Wizard 12.8 Crack License Key LATEST
hashhshs786
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
Technical-Careers-Roadmap-in-Software-Market.pdf
Hussein Ali
 
Generic or Specific? Making sensible software design decisions
Bert Jan Schrijver
 
ChiSquare Procedure in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
Help for Correlations in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Digger Solo: Semantic search and maps for your local files
seanpedersen96
 
Customise Your Correlation Table in IBM SPSS Statistics.pptx
Version 1 Analytics
 
Agentic Automation Journey Session 1/5: Context Grounding and Autopilot for E...
klpathrudu
 
Agentic Automation: Build & Deploy Your First UiPath Agent
klpathrudu
 
Build It, Buy It, or Already Got It? Make Smarter Martech Decisions
bbedford2
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
유니티에서 Burst Compiler+ThreadedJobs+SIMD 적용사례
Seongdae Kim
 
In From the Cold: Open Source as Part of Mainstream Software Asset Management
Shane Coughlan
 

Pybelsberg — Constraint-based Programming in Python

  • 1. Conrad Calmez Christoph Matthies Robert Lehmann Pybelsberg © 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030 1
  • 2. a = pt(100, 100) b = pt(200, 200) always { a.dist(b) == 200 } a.setX(50) a.dist(b) # => 200 babelsberg-js © 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030 https://github.com/timfel/babelsberg-js 2
  • 3. a = pt(100, 100) b = pt(200, 200) always { a.dist(b) == 200 } a.setX(50) a.dist(b) # => 200 © 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030 babelsberg-js 3
  • 4. a = Point(100, 100) b = Point(200, 200) @always def constraint(): return a.dist(b) == 200 a.x = 50 a.dist(b) # => 200 pybelsberg © 2006 by Jeremy Quinn, https://www.flickr.com/photos/sharkbait/314820030 4
  • 6. p = Problem() p.a_x = p.a_y = 100; p.b_x = p.b_y = 200 constraint = … p.always(constraint) print(dist((p.a_x, p.a_y), (p.b_x, p.b_y))) # => 200 Boilerplate 6
  • 7. p = Problem() p.a_x = p.a_y = 100; p.b_x = p.b_y = 200 constraint = … p.always(constraint) print(dist((p.a_x, p.a_y), (p.b_x, p.b_y))) # => 200 Boilerplate ? 7
  • 9. 100 200 100 200 a.x f(a.x) = √(a.x−b.x)² + (a.y−b.y)² f(a.x) = 200 9 a b
  • 10. 100 200 100 200 a.x f(a.x) = √(a.x−b.x)² + (a.y−b.y)² f(a.x) = 200 f 10 a b
  • 11. 100 200 100 200 a.x f(a.x) = √(a.x−b.x)² + (a.y−b.y)² f(a.x) = 200 g(a.x) = f(a.x) − 200 = 0 11 a b
  • 13. def constraint(a_x, a_y, b_x, b_y): return dist((a_x, a_y), (b_x, b_y)) — 200 1 Defining the constraint actually: f(a.x, a.y, b.x, b.y) = √(a.x−b.x)² + (a.y−b.y)² 13
  • 14. Satisfying constraints ● Finding values to satisfy constraints is solving equations. ● Solving equations means finding the root of polynomials. dist((a_x, a_y), (b_x, b_y)) — 200) 14
  • 15. def constraint(a_x, a_y, b_x, b_y): return dist((a_x, a_y), (b_x, b_y)) — 200 def constraint(a_x, a_y, b_x, b_y): return dist((a_x, a_y), (b_x, b_y)) == 200 2 Define constraints naturally 15
  • 16. class Expr(object): def __add__(self, other): return Expr('+', self, other) def __eq__(self, other): return Expr('=', self, other) … def to_eval(self): return self.left.to_eval() + self.operator + self.right.to_eval() Remember performed operations 16
  • 17. def constraint(a_x, a_y, b_x, b_y): return dist((a_x, a_y), (b_x, b_y)) == 200 3 No explicit declaration of parameters 17
  • 18. def foo(): x foo() # => NameError: global name 'x' is not defined Variables in functions 18
  • 19. class Namespace(dict): def __getattr__(self, key): print("getattr", key) def foo(): a + b ns = Namespace() proxy = types.FunctionType(foo.__code__, ns) proxy() # => ??? Execute function in different global scope 19
  • 20. Execute function in different global scope class Namespace(dict): def __getattr__(self, key): print("getattr", key) def foo(): a + b ns = Namespace() proxy = types.FunctionType(foo.__code__, ns) proxy() # => getattr a # => getattr b 20
  • 21. 2.7.6 case LOAD_GLOBAL: w = GETITEM(names, oparg); x = PyDict_GetItem(f->f_globals, w); PUSH(x); 3.3.5 TARGET(LOAD_GLOBAL) w = GETITEM(names, oparg); if (PyDict_CheckExact(f->f_globals)) { … } else { /* Slow-path if globals or builtins is not a dict */ x = PyObject_GetItem(f->f_globals, w); … } PUSH(x); CPython: Python/ceval.c 21
  • 22. def constraint(): return dist((a_x, a_y), (b_x, b_y)) == 200 a_x = 50 print(a_x, a_y, b_x, b_y) # => 50 100 200 -32.14 print(dist(a_x, a_y), (b_x, b_y))) # => 200 4 Work with global variables 22
  • 23. TARGET(STORE_FAST) v = POP(); // SETLOCAL(oparg, v); PyObject *tmp = fastlocals[i]; fastlocals[i] = value; Py_XDECREF(tmp); FAST_DISPATCH(); CPython: Python/ceval.c no Python protocol is used -- GAME OVER 23
  • 24. class Namespace(dict): def __setattr__(self, key): print("setattr", key) def foo(): global a a = 2 ns = Namespace() proxy = types.FunctionType(foo.__code__, ns) proxy() # => no output ☹ Function globals can be overridden? 24
  • 25. TARGET(STORE_GLOBAL) { PyObject *name = GETITEM(names, oparg); PyObject *v = POP(); int err; err = PyDict_SetItem(f->f_globals, name, v); Py_DECREF(v); if (err != 0) goto error; DISPATCH(); } GAME OVER -- bug, see ticket #1402289 CPython: Python/ceval.c 25
  • 26. class in_constrained(constraint): a_x = 50 Use class as scope 26
  • 27. class Namespace(dict): def __setitem__(self, key, val): print("setitem", key, val) class Meta(type): def __prepare__(self, obj): return Namespace() class Object(metaclass=Meta): x = 2 # => setitem __module__ __main__ # => setitem __qualname__ Object # => setitem x 2 Use class as scope 27
  • 28. class Namespace(dict): def __setitem__(self, key, val): print("setitem", key, val) class Meta(type): def __prepare__(self, obj): return Namespace() class Object(metaclass=Meta): x = 2 # => setitem __module__ __main__ # => setitem __qualname__ Object # => setitem x 2 Use class as scope Stamp © 2012 Stuart Miles, FreeDigitalPhotos.net, http://www.freedigitalphotos.net/images/Other_Metaphors_and__g307-Reject_Stamp_p86053.html 28
  • 29. a = Point(100, 100) b = Point(200, 200) @always def point_distance_constraint(): return a.dist(b) == 200 a.x = 50 # a.__setattr__('x', 50) ~› solve() a.dist(b) # => 200 5 Catch instance variables 29
  • 30. class A(object): pass def setattr(self, name, value): print("setattr", name, value) a = A() a.__setattr__ = setattr a.x = 10 # no output ☹ Notice instance variable assignment 30
  • 31. 3.3.5 int PyObject_SetAttr(PyObject *v, PyObject *name, PyObject *value) { PyTypeObject *tp = Py_TYPE(v); int err; Py_INCREF(name); if (tp->tp_setattr != NULL) { err = (*tp->tp_setattr)(v, name_str, value); Py_DECREF(name); return err; } … return -1; } CPython: Objects/object. c 31
  • 32. class A(object): pass def setattr(self, name, value): print("setattr", name, value) a = A() type(a).__setattr__ = setattr a.x = 10 # => setattr x 10 Use type 32
  • 33. always: a.dist(b) == 200 6 Source code transforms 33
  • 34. import codecs def decode(text): return u'x=5n' + text.decode('utf8') codecs.register('babelsberg', decode) # encoding: babelsberg print(x) # => 5 Custom encoding * * not the actual codecs API 34
  • 35. ## main.py ☹ import custom_codec import demo ## demo.py # encoding: babelsberg print(x) # => 5 Custom encoding, caveat depends on 35
  • 36. ## main.py ☹ import custom_codec import demo ## demo.py # encoding: babelsberg print(x) # => 5 Custom encoding, caveat 36
  • 37. <demo> a = Point(100.0, 100.0) b = Point(200.0, 200.0) @always def constant_distance(): yield a.distance(b) == 200 assert_almost_equals(a.distance(b), 200) a.x = 50 assert_almost_equals(a.distance(b), 200) 37
  • 38. 0 LOAD_GLOBAL 0 (a) 3 LOAD_ATTR 1 (dist) 6 LOAD_GLOBAL 2 (b) 9 CALL_FUNCTION 1 12 LOAD_CONST 1 (200) 15 COMPARE_OP 2 (==) 18 POP_TOP 19 LOAD_CONST 0 (None) 22 RETURN_VALUE a = Point(100, 100) b = Point(200, 200) @always def constant_distance(): a.dist(b) == 200 patch(obj): for each instance variable of obj: remember original value replace with wrapped valuea.x, a.y, b.x, b.y 38
  • 39. constraint = constant_distance() for all remembered instance variables: solver.add(instance_variable == value) solver.add(constraint) solver.solve() (= 200 (sqrt (+ (** (- a.x b.x) 2) (** (- a.y b.y) 2) ))) 39
  • 42. scipy.optimize.fsolve( func, #A function that takes at least one argument. x0, #The starting estimate for the roots of func(x) = 0. args=(), #Any extra arguments to func. fprime=None, #A function to compute the Jacobian of func with derivatives across the rows. By default, the Jacobian will be estimated. full_output=0, #If True, return optional outputs. col_deriv=0, #Specify whether the Jacobian function computes derivatives down the columns (faster, because there is no transpose operation). xtol=1.49012e-08, #The calculation will terminate if the relative error between two consecutive iterates is at most xtol maxfev=0, #The maximum number of calls to the function. If zero, then 100*(N+1) is the maximum where N is the number of elements in x0. band=None, #If set to a two-sequence containing the number of sub- and super-diagonals within the band of the Jacobi matrix, the Jacobi matrix is considered banded (only for fprime=None). epsfcn=None, #A suitable step length for the forward-difference approximation of the Jacobian (for fprime=None). If epsfcn is less than the machine precision, it is assumed that the relative errors in the functions are of the order of the machine precision. 42
  • 43. scipy.optimize.fsolve constraint = lambda args: [ math.sqrt( (args[0]-args[1])**2 + (args[2]-args[3])**2 ) - 200 ]*4 fsolve(constraint, [1, 1, 1, 1]) # => (array([ 201., 1., 1., 1.]) starting values 43
  • 44. scipy.optimize.fsolve ● Requires transformation ○ “Return the roots of the (non-linear) equations defined by func(x) = 0” ○ Cannot access instance variables ○ Function value must be closer to 0 if the parameters are closer to the solution ○ x = y → x - y = 0 x > y → x - y if x - y > 0 else 0 ● Requires starting estimate ○ Hard to determine best value for user-defined equations 44
  • 45. Z3 45
  • 46. Z3 theorem prover ● Developed by Microsoft Research http://z3.codeplex.com/ ● General-purpose solver (not only for finding roots) ● Many built-in theories ○ linear arithmetic, nonlinear arithmetic, bitvectors, arrays, datatypes, quantifiers ● Python bindings ○ already does ASTs 46
  • 47. from z3 import * a_x, a_y = Real('a.x'), Real('a.y') b_x, b_y = Real('b.x'), Real('b.y') s = Solver() s.add(a_x == 100, …) s.add(sqrt((a_x-b_x)**2 + (a_y-b_y)**2) == 200) print(s.check()) # => sat print(s.model()) # => [a.x = 26.79, a.y = 100, …] Z3 theorem prover 47
  • 48. Z3 theorem prover ● Quality of life improvement ○ Try to minimize the amount of variables that are changed by the solver due to a constraint 48
  • 49. Add all constraints ● Put a rollback point (“push” in Z3 lingo) ● Add all current variables (eg. from Point constructor, example a = Point(50, 100)) as “soft constraints” ○ ie., boolnew → a.x = 50 ● Solver tells us which implications are wrong (were invalidated to satisfy constraints) ● We remove these from future runs, so that these variables are preferably modified Z3 theorem prover 49
  • 50. s.add(sqrt((a.x - b.x)**2 … == 200) s.push() s.add(a.x == 100, a.y == 100, b.x == 50, b.y == 50) s.check() # => unsat, a.x s.pop() s.add(a.x == 100, a.y == 100, …) s.check() # => sat transaction 50
  • 51. © 2008 by “GillyBerlin”, flickr.com/photos/gillyberlin/2531057541 (CC BY 2.0) ● Constraint-based programming with object-oriented Python ● Leverage same advanced solver as Babelsberg/JS ● Quality of life improvements for the programmer 51