/PyClause

A libary for using and learning symbolic rules for knowledge graphs

Primary LanguageC++

PyClause

PyClause is a library for easy and efficient usage and learning of symbolic knowledge graph rules of the following form.

citizenOf(X,Y) <= bornIn(X,A), locatedIn(A,Y)
speaks(X,english) <= lives(X,london)

Documentation

Documentation of library and features can be found here.
All usable default options for the configuration files can be found in clause/config-default.yaml

Installation

PyClause only uses a few lightweight Python dependencies and runs under Windows and Linux systems. Linux users need to have a c++ (14) compiler installed. Windows users need to have C++ build tools installed. PyClause requires Microsoft Visual C++ 14.0 or newer.

We recommend using a fresh Conda environment with Python 3.7+.

1) Install from codebase

For running our examples and using our data directories or working with the code

git clone https://github.com/symbolic-kg/PyClause
cd PyClause
pip install -e .

2) Install as a package

For using PyClause in your own Python project and as a dependency. When running our examples, you have to set your own correct paths to data and rule files.
install:

pip install git+https://github.com/symbolic-kg/PyClause.git

as dependency:

## in setup.py

setup(
  name             = "MyProject",
  install_requires = ["PyClause @ git+https://github.com/symbolic-kg/PyClause.git#egg=PyClause"],
  python_requires  = ">=3.7"
)

Quickstart

After installing PyClause with any of the two options, run the following code from anywhere.

from c_clause import QAHandler, Loader
from clause import Options

# ***Example for Query Answering***

# define a knowledge graph
# alternatively, specify file path or use arrays + indices
data = [
    ("anna", "livesIn", "london"),
    ("anna", "learns", "english"),
    ("bernd", "speaks", "french")
]
# define rules, or specify file path
rules = [
     "speaks(X,Y) <= learns(X,Y)",
     "speaks(X,english) <= livesIn(X,london)",
     "speaks(X,english) <= speaks(X,A)"
]
# define rule stats: num_preds, support
stats = [
    [20, 10],
    [40, 35],
    [50, 5],
]
# define options, handlers and load data
opts = Options()
opts.set("qa_handler.aggregation_function", "noisyor")

loader = Loader(options=opts.get("loader"))
loader.load_data(data)
loader.load_rules(rules=rules, stats=stats)

qa = QAHandler(options=opts.get("qa_handler"))
# define query: (anna, speaks, ?); alternatively, use indices
queries = [("anna", "speaks")]
qa.calculate_answers(queries=queries, loader=loader, direction="tail")
# outputs [("english", 0.867 )] 
print(qa.get_answers(as_string=True)[0])

# define query: (?, speaks, english); alternatively, use indices
queries = [("english", "speaks")]
qa.calculate_answers(queries=queries, loader=loader, direction="head")
# outputs [('anna', 0.867), ('bernd', 0.001)] 
print(qa.get_answers(as_string=True)[0])

Run tests (for developers, linux)

Download this, unpack, and put the folders into data/
Then, from the base directory run pytest -s.

Colophon

Have you spotted it?

The PyClause logo is a reminiscence of Freges Begriffsschrift, which has been published in the year 1879. Even though Frege is not well known in computer science, in his book Begriffsschrift he developed a calculus using an uncommon notation, which is essentially second-order logic with identity (an extension of first-order logic).

The blue lines in the logo are Freges way to express an implication. If we would write A at the end of the first line and B at the end of the second line, this would correspond to a logical rule A <= B, which can again be understood as a clause with a positive and a negative literal. The round dint at the beginning is Freges way to express universal quantification. For more details we refer to the Wikipedia article or the book from 1879 entitled Begriffsschrift.