Yuce's Blog

Cognitive dissonance is yoga for the brain.*

PySWIP: Facts and Rules

2009-10-08

PySWIP is a Python module which enables accessing SWI-Prolog's foreign language interface using our beloved computer language. Here's a small tutorial on adding facts and rules to prolog knowl­edge­base.

First, adding facts and rules, based on examples in a Prolog tutorial.

from pyswip import Prolog
p = Prolog()

# something is fun if it is a car and it is red.
p.assertz('(fun(X) :- red(X), car(X))')

# facts...
p.assertz('car(vw_beatle)')
p.assertz('car(ferrari)')
p.assertz('car(hyundai)')
p.assertz('bike(harley_davidson)')
p.assertz('red(ferrari)')
p.assertz('red(vw_beatle)')
p.assertz('blue(hyundai)')

Find all cars in the knowl­edge­base:

print list(p.query('car(Which)'))

Outputs:

[{'Which':'vw_beatle'}, {'Which':'ferrari'}, {'Which':'hyundai'}]

Find all fun things:

print list(p.query('fun(What)'))

Outputs:

[{'What':'vw_beatle'}, {'What':'ferrari'}]

Pretty easy, huh? ;) There are more complex Prolog examples in PySWIP source dis­tri­b­u­tion, including a sudoku solver.

Comment

python, prolog, pyswip

Getting the Currently Playing Song Info on Amarok via DCOP

2009-08-13

Here's a sample ap­pli­ca­tion for using DCOP with Python. Needed to install python-dcop on Debian. It works on KDE 3.5 with Amarok 1.4 (won't work on KDE 4)

import pydcop

playerService = pydcop.DCOPObject('amarok', 'player')

d = dict(
   title=playerService.title(),
   artist=playerService.artist(),
   album=playerService.album()
)
print '%(artist)s - %(title)s (%(album)s)' % d

kdcop is a great ap­pli­ca­tion to discover DCOP services.

I've posted a slightly extended version of this entry to Active State Python Cookbook.

Comment

python, DCOP, amarok, KDE

Ctypes Strings

2007-05-28

I've written bulk of PySWIP last summer, it is based on Nathan Denny's proolog.py. This is the first project that I used ctypes, a fantastic package which allows calling C functions from dynamic libraries that I use to link libpl.so (Linux) or libpl.dll (Windows) of SWI-Prolog. One of the dif­fi­cul­ties I had back then was finding the cor­re­spond­ing ctypes code for PL_get_chars which is defined at SWI-Prolog.h as follows:

PL_EXPORT(int) PL_get_chars(term_t t,
    char **s, unsigned int flags);

I use that function in queryGenerator:

answer = (c_char_p*maxsubresult)()
while PL_get_list(swipl_list, swipl_head, swipl_list):
    PL_get_chars(swipl_head, answer,
        CVT_ALL 
continue.
Comment

python, ctypes, prolog, pyswip

SEND + MORE + MONEY

2007-05-27

Finding valid and distinct integers for digits S, E, N, D, M, O, R and Y in the equation SEND + MORE = MONEY is a classical constraint pro­gram­ming problem. Here's the slightly modified version of the sample program at Wikipedia constraint pro­gram­ming entry for SWI-Prolog using clp library:

:- use_module(library('clp/bounds')).

sendmore(Digits) :-
   Digits = [S,E,N,D,M,O,R,Y],
   Digits in 0..9,
   S #\= 0,
   M #\= 0,
   all_different(Digits),
                1000*S + 100*E + 10*N + D
      
continue.
Comment

send more money, sendmory, constraint programming, prolog

Eclipse Workspace Problem

2007-03-04

Today, while commiting Biz, Eclipse locked up, and after that it didn't get past the slash screen in the subsequent runs. I've wasted some time to fix it, and here is a simple solution: Just delete ~/workspace/.metadata/.plugins/org.eclipse.ui.workbench and you're good ((assuming your workspace is ~/workspace) .

Comment

eclipse, problem, fix

Shameful Past

2005-10-24

A few hours ago, when I was dealing with my thesis, I've come up with a Python function that constructs a tour for a given TSP instance using the nearest neighbor heuristic:

def nearestneighbor(size, dists):
   tour = [0]*size
   candy = [True]*size
   candy[0] = False

   for i in range(1, size):
       prev = tour[i - 1]
       tour[i] = min([(dists[prev][c], c)
           for c in range(size) if candy[c] and  c != prev])[1]
   
continue.
Comment

python, shame on you, nearest neighbor

Freeeze for Marvin3

2005-10-17

Today, I added a keyword called freeze to Marvin3. Basically, when called inside a routine, it pops the top element from the stack and replaces routine's code with a word that pushes that value onto the stack. This way we can create a write-once routine, which is similar to C#'s readonly modifier (value is allowed to be set once). Consider the following example:

:YOUR-NUMBER input int freeze ;

"Enter a number:" prints YOUR-NUMBER
YOUR-NUMBER " is a nice number!" cat println

Notice that, although YOUR-NUMBER is a routine, when called, it just pushes the same value determined when it is first called.

Here is a more complex one. continue.

Comment

marvin3

99 Bottles of Beer in Marvin3

2005-09-29

How to write 99 bottles of beer in Marvin3?

:bottles  dup dup 1 > [" bottles"] [" bottle"] ifte cat ;

:sing
    bottles dup " of beer on the wall," cat println
    " of beer. " cat println
    "Take one down, pass it around." println ;

:theend  "No more beer left." println ;

:beers  [dup 0 >] [sing decr] while theend eat ;

# start singing
99 beers

Also you may check a previous post for the original Marvin. Other languages? 99 Bottles of Beer on the Wall lists many. See 99 Bottles of Beer on Wikipedia.

Comment

marvin3, marvin, 99 bottles