-
Notifications
You must be signed in to change notification settings - Fork 20
Program
A Tensorlog PROGRAM usually has extension .ppr. Some examples (for version 1.1):
predict(X,Pos) :- assign(Pos,pos) {all(F): hasWord(X,W),posPair(W,F)}.
predict(X,Neg) :- assign(Neg,neg) {all(F): hasWord(X,W),negPair(W,F)}.
match(R,S) :- fname(R,FR),fmatch(FR,FS),fname(S,FS) {f}.
match(R,S) :- lname(R,LR),lmatch(LR,LS),lname(S,LS) {l}.
match(R,S) :- addr(R,AR),amatch(AR,AS),addr(S,AS) {a}.
For version 1.2.3 and up, instead of using 'all', and having the system convert this to the parameter 'weighted', you replace 'all' with a parameter name. For example, you can introduce two parameters, one for each class, and use these rules:
predict(X,Pos) :- assign(Pos,pos) {posWeighted(W): hasWord(X,W)}.
predict(X,Neg) :- assign(Neg,neg) {negWeighted(W): hasWord(X,W)}.
These are syntactic sugar for ordinary definite clauses: some examples of the sugar-free version are below. Briefly, the literal before the ':' is placed at the end of the literals after it, and the result is just spliced into the rule body; and when 'c' is a constant, {c} is converted to {weighted(C):assert(C,c)}.
predict(X,Neg) :- assign(Neg,neg) {negWeighted(W): hasWord(X,W)}. #proppr syntax
predict(X,Neg) :- assign(Neg,neg), hasWord(X,W), negWeighted(W). #sugar-free
match(R,S) :- addr(R,AR),amatch(AR,AS),addr(S,AS) {a}. #proppr syntax
match(R,S) :- addr(R,AR),amatch(AR,AS),addr(S,AS), assign(A,a), weighted(A). #sugar-free
If you use the ProPPR-style rule features (in the curly braces) you should make sure any constants appearing there are in the database. My convention is to create a unary 'ruleid' relation in a .cfacts file.
To find all constant rule ids in a ProPPR program in you can use the 'list' module:
python -m tensorlog.list --prog test-data/matchtoy.ppr --ruleIds
There's no serialized form of a program.
If your database is type, you should use assign(Var,const,type) instead of the 2-argument assign predicate, eg:
predict(X,Pos) :- assign(Pos,pos,label) {all(F): hasWord(X,W),posPair(W,F)}.
There's a more Pythonic syntax for rules, which can be used to create rules programmatically, described in the docs for tensorlog.simple.Builder class. Briefly, some examples are:
from tensorlog import simple
b = simple.Builder()
X,Y,Z = b.variables("X Y Z")
aunt,parent,sister,wife = b.predicates("aunt parent sister wife")
uncle = b.predicate("uncle")
b.rules += aunt(X,Y) <= parent(X,Z),sister(Z,Y)
b.rule += aunt(X,Y) <= uncle(X,Z),wife(Z,Y)
Or, with 'control' on the rules:
r1,r2 = b.rule_ids("r1 r2")
...
b.rules += aunt(X,Y) <= uncle(X,Z) & wife(Z,Y) // r1
b.rules += aunt(X,Y) <= parent(X,Z) & sister(Z,Y) // r2
b.rules += aunt(X,Y) <= uncle(X,Z) & wife(Z,Y) // (weight(F) | description(X,D) & feature(X,F))