1 / 24

Programming declaratively in C++ using the Logic paradigm

Programming declaratively in C++ using the Logic paradigm. Roshan Naik Hewlett Packard Co. roshan@mpprogramming.com 16 th April 2008 Northwest C++ Users Group Redmond, WA . Agenda. Introduction to Logic Programming (LP) concepts.

moriah
Download Presentation

Programming declaratively in C++ using the Logic paradigm

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Programming declaratively in C++ using the Logic paradigm Roshan Naik Hewlett Packard Co. roshan@mpprogramming.com 16th April 2008 Northwest C++ Users Group Redmond, WA

  2. Agenda • Introduction to Logic Programming (LP) concepts. • Introduction to facilities available for LP in C++. Will use the open source library : Castor (www.mpprogramming.com). • Live examples. From trivial to simple to more complex ones.

  3. Underlying Theme • LP as a general purpose programming. • Demonstrate Multiparadigm Programming by mixing LP with the Imperative, Object-oriented, Functional and Generic paradigms.

  4. Logic Paradigm (LP) • Computational model: Predicate calculus (Turing complete). • Declarative : Focuses on what to compute not how. • Holy Grail of programming: “The user states the problem, the computer solves it”. LP is one approach in Computer Science. • Basic mechanics of LP • Programmer provides sufficient information to the computer. • By using relations • Computer employs a general purpose problem solving technique. • By using backtracking and unification.

  5. Declarative vs. Imperative • Why are most programming languages imperative ? • What is a key weakness of declarative programming ? • What is a key weakness of imperative programming ?

  6. “relation” • A set is a collection of (unique) objects. • A simple way of thinking about relations is as an association/mapping between elements in two or more sets. People Frank Sam Mary Denise Genders Male Female GenderOf (Frank, Male) (Sam, Male) (Mary, Female) (Denise, Female)

  7. “relation” • A relation is essentially a set. • Thinking of relations as mappings between sets really helps when designing relations in LP. • A relation is to the logic paradigm what a function is to the imperative paradigm.

  8. Functions vs. Relations GenderOf (Frank, Male) (Sam, Male) (Mary, Female) (Denise, Female) • As functions // check if (p,g) bool checkGender(string p, string g) { ... } // get gender of p string genderOf(string p) { ... } // get all people having gender g list<string> havingGender(string g) { ... } // list all (p,g) list<pair<string,string> > getItems() { ... }

  9. Functions vs. Relations • As a relation // declarative reading : p’s gender is g relationgender(lref<string> p, lref<string> g){ return eq(p,”Frank”) && eq(g,”male”) || eq(p,”Sam”) && eq(g,”male”) || eq(p,”Mary”) && eq(g,”female”) || eq(p,”Denise”)&& eq(g,”female”); } • Specification is declarative. • One relation subsumes functionality of all four functions. GenderOf (Frank, Male) (Sam, Male) (Mary, Female) (Denise, Female)

  10. Demo

  11. lref<T> : logic reference • Unlike C++ references, it does not have to be initialized. Use method defined() to check. • Operator * used to access underlying value. cout << *lx; • Internally stores a copyof the value assigned to it. lref<int> li=2; • Copy constructing an lref binds it with source lref. i.e. both refer to the same underlying object. lref<int> lj (li); • Assigning one lref to another simply copies the underlying value over. lref<int> lk; lk=lj;

  12. lref<T> : Logic reference • Initialization lref<int> li1=1, li2;// li2.defined()==false li2=10; // li2.defined()==true • Copy construction lref<int> li3=li1; // co-references li3=5; cout << *li1; // prints 5 • Assignment lref<int> li4 = 4; li4=li1; // copy value from li1 to li4 li1=9; cout << *li1 << ", " << *li4; // prints 9, 1

  13. eq : The unification relation • Attempts to make both arguments equal. • Semantically a combination of == and = if (both args are initialized) return 1stArg == 2ndArg; else uninitializedArg= value of the other; return true; • At least one of the two arguments must be initialized!

  14. The magic type : relation • Represents any function object that produces a bool and takes no arguments. struct FuncObj { booloperator() (void) {...} }; FuncObj f; relation r = f; r();// execute FuncObj::operator() • Type erasure at work • Explicit conversion or assignment operators not needed to assign FuncObj to relation. • FuncObj does not have to inherit from any type or be templated. • Key to smooth integration of paradigms and simple syntax. • Fairly similar to boost::function<bool()>

  15. Disjunction: Operator || relation operator || (relation lhs, relation rhs) Example:foo(…) || bar(…) • In plain English: • Generate all solutions from lhs (one per invocation), then generate all solutions from rhs (one per invocation). • Coroutine style pseudo code (C# like syntax). while( lhs() ) yieldreturntrue; //‘yield’ borrowed from C# while( rhs() ) yieldreturntrue; return false;

  16. Conjunction: Operator && • In plain English: • Produce all solutions (one per invocation) in the 2nd relation for each solution in the 1st relation. • Coroutine style pseudo code (C# like syntax). relation tmp = rhs; //make copy of rhs while( lhs() ) { while( rhs() ) yieldreturntrue; //‘yield’ borrowed from C# rhs = tmp; //reset rhs } returnfalse;

  17. Exclusive Disjunction: Operator ^ • In plain English: • Generate solutions from 2nd relation (one per invocation), only if 1st relation did not produce any. • Coroutine style pseudo code (C# like syntax). bool lhsSucceded = false; while( lhs() ) { lhsSucceded = true; yieldreturntrue; } while(!lhsSucceded && rhs()) yieldreturntrue; returnfalse;

  18. Examples • Demo

  19. 1 2 5 3 4 Directed Acyclic Graphs // Edges in the graph relation edge(lref<int> n1, lref<int> n2) { returneq(n1,1) && eq(n2,2) ||eq(n1,2) && eq(n2,3) ||eq(n1,3) && eq(n2,4) ||eq(n1,5) && eq(n2,4) ||eq(n1,5) && eq(n2,2) ; } // Definition of path relation path(lref<int> start, lref<int> end) { lref<int> nodeX; return edge(start, end) || edge(start, nodeX) && recurse(path,nodeX,end); }

  20. Disjunctions : Dynamic relations • Think of it as a dynamic list of clauses separated by || operator. • Disjunctions is itself a relation. relation edge(lref<int> n1, lref<int> n2) { Disjunctions result; result.push_back(eq(n1,1) && eq(n2,2) ); result.push_back(eq(n1,2) && eq(n2,3) ); ... return result; }

  21. Examples • Demo

  22. Castor • About: • Pure header library (i.e. nothing to link). • Download from www.mpprogramming.com • Open source. (MIT License). • Sourceforge project name: castor-logic • Compilers supported: • aCC, A.06.15 (Mar 28 2007) • Borland C++ Builder 2007 • GCC, v4.1.0 (and above) • Microsoft Visual C++ 2005 and 2008

  23. More information • Introduction to Logic Programming with C++ • www.mpprogramming.com/resources/CastorTutorial.pdf • Castor reference manual • www.mpprogramming.com/resources/CastorReference.pdf • Blending the Logic Programming Paradigm into C++ (on design & implementation of Castor) • www.mpprogramming.com/resources/CastorDesign.pdf • RSS feed on mpprogramming.com for updates.

  24. Q / A

More Related