Pytholog Tool (Command line & API)

Pytholog tool is an executable tool, built in python, that enables logic programming and prolog syntax through interactive shell that mimics prolog language and / or RESTful API that can be called from other applications.

The tool is based on the python library pytholog which can be found here: https://github.com/mnoorfawi/pytholog

The tool is made from the Pytholog.py script using pyinstaller with the following command: pyinstaller --noconfirm --onefile --console --hidden-import=pkg_resources.py2_warn --icon "pytholog-logo2.ico" "Pytholog.py"

The tool starts normally from the command line. Let's look at the arguments that can be specified while initiating the tool:

$ ./Pytholog -h
usage: Pytholog [-h] [-c CONSULT] -n NAME [-i] [-a]

pytholog executable tool: prolog experience at command line and a logic knowledge base with no dependencies

optional arguments:
  -h, --help            show this help message and exit
  -c CONSULT, --consult CONSULT
                        read an existing prolog file/knowledge base
  -n NAME, --name NAME  knowledge base name
  -i, --interactive     start an interactive prolog-like session
  -a, --api             start a flask api

As we can see, we have 4 parameters: -n --name which is the only required parameter that is used to give a name to the session, -c --consult which can be used in case we have a pre-existing knowledge base, -i --interactive to start an interactive prolog-like session and -a --api that starts a RESTful API written in python/flask. By default it starts the API.

Let's now try the tool with the accompanied dummy knowledge base

First, the interactive shell

$ ./Pytholog -c dummy.txt -n dummy -i

facts and rules have been added to dummy.db
?- prin
invalid input
 please type 'print' to print the knowledge base
 or 'quit' to save and exit
?- print
[likes(assel,limonade), likes(dmitry,cookie), likes(melissa,pasta), likes(nikita,sausage), likes(noor,sausage)]
[food_type(cookie,dessert), food_type(gouda,cheese), food_type(limonade,juice), food_type(ritz,cracker), food_type(sausage,meat), food_type(steak,meat)]
[flavor(savory,meat), flavor(savory,cheese), flavor(sweet,dessert), flavor(sweet,juice)]
[food_flavor(X,Y):-food_type(X,Z),flavor(Y,Z)]
?- likes(noor, sausage)?
['Yes']
?- likes(nikita, cheese)?
['No']
?- likes(noor, What)?
[{'What': 'sausage'}]
?- food_flavor(What, sweet)?
[{'What': 'cookie'}, {'What': 'limonade'}]
?- dish_to_like(X, Y) :- likes(X, L), food_type(L, T), flavor(F, T), food_flavor(Y, F).
?- dish_to_like(noor, What)!
[{'What': 'gouda'}]
?- quit
KnowledgeBase is saved into dummy.pl file

Note the usage of '.' is optional and '?' is required to differentiate between a query and a new fact to be inserted to the knowledge base. And the '!' is used to cut and return the first encountered answer.

Now the API

$ ./Pytholog -c dummy.txt -n dummy -a

facts and rules have been added to dummy.db
 * Serving Flask app "Pytholog" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
facts and rules have been added to dummy.db
 * Debugger is active!
 * Debugger PIN: 222-740-882

Let's try to call the API from command line, python and R and in the browser

Note that spaces can cause some errors

From R

library(httr)
library(jsonlite)

GET("http://127.0.0.1:5000/query?expr=food_flavor(What,savory)")

# Response [http://127.0.0.1:5000/query?expr=food_flavor(What,savory)]
#   Date: 2020-11-13 19:26
#   Status: 200
#   Content-Type: application/json
#   Size: 94 B
# [
#   {
#     "What": "gouda"
#   }, 
#   {
#     "What": "sausage"
#   }, 
#   {
#     "What": "steak"
#   }
# ...

From Command line

$ curl -s -X POST "http://127.0.0.1:5000/insert?expr=dish_to_like(X,Y):-likes(X,L),food_type(L,T),flavor(F,T),food_flavor(Y,F)"
"OK"

From python

import json
import requests

url = "http://127.0.0.1:5000/query?expr=dish_to_like(noor,What)!"
r = requests.get(url)

d = json.loads(r.content)
d

# [{'What': 'gouda'}]

From browser put this into the browser http://127.0.0.1:5000/save and it will give you "KnowledgeBase is saved into dummy.pl file" and a dummy.pl file will be created.