Package: miniKanren
kanrenLogic/relational programming in Python withminiKanren.InstallationUsingpip:pipinstallminiKanrenUsingconda:condainstall-cconda-forgeminiKanrenDevelopmentFirst obtain the project source:gitclonegit@github.com:pythological/kanren.gitcdkanrenInstall the development dependencies:$pipinstall-rrequirements.txtSet uppre-commithooks:$pre-commitinstall--install-hooksTests can be run with the providedMakefile:makecheckMotivationLogic programming is a general programming paradigm.  This implementation however came about specifically to serve as an algorithmic core for Computer Algebra Systems in Python and for the automated generation and optimization of numeric software.  Domain specific languages, code generation, and compilers have recently been a hot topic in the Scientific Python community.kanrenaims to be a low-level core for these projects.These points—along withkanrenexamples—are covered in the paper"miniKanren as a Tool for Symbolic Computation in Python".Exampleskanrenenables one to express sophisticated relations—in the form ofgoals—and generate values that satisfy the relations.  The following code is the "Hello, world!" of logic programming; it asks for values of thelogic variablexsuch thatx == 5:>>>fromkanrenimportrun,eq,membero,var,lall>>>x=var()>>>run(1,x,eq(x,5))(5,)Multiple logic variables and goals can be used simultaneously.  The following code asks for one list containing the values ofxandzsuch thatx == zandz == 3:>>>z=var()>>>run(1,[x,z],eq(x,z),eq(z,3))([3,3],)kanrenusesunificationto match forms within expression trees.  The following code asks for values ofxsuch that(1, 2) == (1, x):>>>run(1,x,eq((1,2),(1,x)))(2,)The above examples useeq: agoal constructorthat creates a goal for unification between two objects.  Other goal constructors, such asmembero(item, coll), express more sophisticated relations and are often constructed from simpler ones likeeq.  More specifically,memberostates thatitemis a member of the collectioncoll.The following example usesmemberoto ask forallvalues ofx, such thatxis a member of(1, 2, 3)andxis a member of(2, 3, 4).>>>run(0,x,membero(x,(1,2,3)),# x is a member of (1, 2, 3)membero(x,(2,3,4)))# x is a member of (2, 3, 4)(2,3)The examples above made implicit use of the goal constructorslallandlany, which represent goalconjunctionanddisjunction, respectively.  Many useful relations can be expressed withlall,lany, andeqalone, but inkanrenit's also easy to leverage the host language and explicitly create any relation expressible in Python.Representing Knowledgekanrenstores data as facts that state relationships between terms.  The following code creates a parent relationship and uses it to state facts about who is a parent of whom within the Simpsons family:>>>fromkanrenimportRelation,facts>>>parent=Relation()>>>facts(parent,("Homer","Bart"),...("Homer","Lisa"),...("Abe","Homer"))>>>run(1,x,parent(x,"Bart"))('Homer',)>>>run(2,x,parent("Homer",x))('Lisa','Bart')We can use intermediate variables for more complex queries.  For instance, who is Bart's grandfather?>>>grandparent_lv,parent_lv=var(),var()>>>run(1,grandparent_lv,parent(grandparent_lv,parent_lv),parent(parent_lv,'Bart'))('Abe',)We can express the grandfather relationship as a distinct relation by creating a goal constructor:>>>defgrandparent(x,z):...y=var()...returnlall(parent(x,y),parent(y,z))>>>run(1,x,grandparent(x,'Bart'))('Abe,')Constraintskanrenprovides a fully functional constraint system that allows one to restrict unification and object types:>>>fromkanren.constraintsimportneq,isinstanceo>>>run(0,x,...neq(x,1),# Not "equal" to 1...neq(x,3),# Not "equal" to 3...membero(x,(1,2,3)))(2,)>>>fromnumbersimportIntegral>>>run(0,x,...isinstanceo(x,Integral),# `x` must be of type `Integral`...membero(x,(1.1,2,3.2,4)))(2,4)Graph Relationskanrencomes with support for relational graph operations suitable for basic symbolic algebra operations.  See the examples indoc/graphs.md.Extendingkanrenkanrenusesmultipledispatchand thelogical-unificationlibraryto support pattern matching on user defined types.  Essentially, types that can be unified can be used with mostkanrengoals.  See thelogical-unificationproject's examplesfor demonstrations of how arbitrary types can be made unifiable.AboutThis project is a fork oflogpy.ReferencesLogic Programming on wikipediaminiKanren, a Scheme library for relational programming on which this library is based.  More information can be found in thethesis of William
Byrd.