Printer Friendly
The Free Library
14,670,786 articles and books
Member login
User name  
Password 
 
Join us Forgot password?

Logic programming with Perl and Prolog.


Computing languages can be addictive; developers sometimes blame themselves for perceived inadequacies, making apologies for them. That is the case, at least, when one defends his or her language of choice against the criticism of another language's devotee. Regardless, many programmers prefer one language, and typically ground that preference in a respect for that language's strengths.

Perl has many strengths, but two most often cited are its adaptability and propensity to work as a "glue" between applications and/or data. However, Perl isn't the only advantageous language: programmers have used C or even assembly to gain speed for years, and intelligent use of SQL SQL
 in full Structured Query Language.

Computer programming language used for retrieving records or parts of records in databases and performing various calculations before displaying the results.
 allows the keen coder to offload To remove work from one computer and do it on another. See cooperative processing.  difficult data manipulations Processing data.  onto a database, for example. Prolog (PROgramming in LOGic) A programming language used for developing AI applications (natural language translation, expert systems, abstract problem solving, etc.). Developed in France in 1973, "Programmation en Logique" is used throughout Europe and Japan and is gaining  is an often overlooked gem that, when combined with the flexibility of Perl, affords the coder powerful ways to address logical relationships and rules. In this article, I hope to provide a glimpse of the benefits that embedded Inserted into. See embedded system.  Prolog offers to Perl programmers. Moreover, I hope that my example implementation demonstrates the ease with which one can address complex logical relationships.

A Bit About Prolog

For the sake of demonstration, I would like to frame a simple problem and solution that illustrate the individual strengths of Perl and Prolog, respectively. However, while I anticipate that the average reader will be familiar with the former, he or she may not be as familiar with the latter. Prolog is a logic programming language often used in AI work, based upon predicate calculus predicate calculus

Part of modern symbolic logic which systematically exhibits the logical relations between propositions involving quantifiers such as “all” and “some.
 and first developed in 1972. There are several excellent, free versions of Prolog available today, including GNU Prolog GNU Prolog (also called gprolog) is a compiler developed by Daniel Diaz with an interactive debugging environment for Prolog available for Unix and Windows. It also supports some extensions to Prolog including constraint programming over a finite domain, parsing using  and the popular SWI SWI Software Interrupt (ARM CPU instruction)
SWI Social Welfare Institute
SWI Secure Windows Initiative (Microsoft)
SWI Steel Window Institute (Cleveland, Ohio) 
 Prolog. For the Prolog initiate, I recommend checking out some of the free Prolog tutorials, either those linked from Wikipedia or from OOPWeb.

Prolog and Perl aren't exactly strangers, however. There are several excellent Perl modules A Perl module is a discrete component of software for the Perl programming language. A module is distinguished by a unique namespace, e.g. "CGI" or "Net::FTP" or "XML::Parser" and a filename similarly named (ie. Net::FTP lives in Net/FTP.pm).  available to allow the coder to access the power of Prolog quite easily, including the SWI module developed by Robert Barta, the Interpeter module by Lee Goddard Lee Goddard (born October 22, 1982) is an English cricketer. He is a right-handed batsman and a wicket-keeper. He has played for Loughborough UCCE, Derbyshire, Yorkshire CB and Durham CCC. , the Yaswi modules developed by Salvador Fandino Garcia, and the AI::Prolog module written by Curtis "Ovid" Poe. Poe has also recently provided a rather nice introduction to Prolog-in-Perl in an online-accessible format.

The Problem

There are many advantages to using Prolog within Perl. In the general sense, each language has its own advantages, and can thus complement the other. Suppose that I am building a testing harness or a logic-based query engine for a web application, where neither language easily provides all of the features I need. In cases such as these, I could use Prolog to provide the logic "muscle," and Perl to "glue" things together with its flexibility and varied, readily available modules on CPAN (Comprehensive Perl Archive Network) The source for knowledge, software and documentation for the Perl programming language. For more information, visit www.cpan.org. See Perl.

CPAN - Comprehensive Perl Archive Network
.

In my simple demonstration, I am going to posit the requirement that I take genealogical ge·ne·al·o·gy  
n. pl. ge·ne·al·o·gies
1. A record or table of the descent of a person, family, or group from an ancestor or ancestors; a family tree.

2. Direct descent from an ancestor; lineage or pedigree.
 reformation built by another application and test relationships based upon a set of rules. In this case, the rules are defined in a Prolog file (an interesting intersection here is that both Perl and Prolog typically use the suffix suf·fix  
n.
An affix added to the end of a word or stem, serving to form a new word or functioning as an inflectional ending, such as -ness in gentleness, -ing in walking, or -s in sits.

tr.v.
 .pl), while the genealogical information is contained in a Dot file readable by Graphviz. As such, I am going to make certain assumptions about the format of the data. Next, I am going to assume that I will have a query (web-based, or from yet another application) that will allow users to identify relationships (such as brothers, cousins, etc.).

Here are my Prolog rules:
DATABASE AND NETWORK INTELLIGENCE

is_father (Person)             :- is_parent (Person, -),
                               is male (Person).
is-father (Person, Child)      :- is_parent (Person, Child)
                               is male (Person).

is-mother (Person)             :- is parent (Person, -),
                               is_female (Person) .
is_mother (Person, Child)      :- is_parent (Person, Child),
                               is_female (Person) .

ancestor (Ancestor, Person)    :- is_parent (Ancestor, Person) .
ancestor (Ancestor, Person)    :- is_parent (Ancestor, Child),
                               ancestor (Child, Person) .

is_sibling (Person, Sibling)   :- is_parent (X, Person),
                               is_parent (X, Sibling) .

is_cousin(Person, Cousin)      :- is_parent (X, Person),
                               is parent (Y, Cousin),
                               is_sibling (X, Y) .


One advantage to separating my logic is that I can troubleshoot it before I even write the Perl code, loading the rules into a Prolog interpreter or IDE (1) (Integrated Development Environment) A set of programs run from a single user interface. For example, programming languages often include a text editor, compiler and debugger, which are all activated and function from a common menu.  such as XGP XGP Xanthogranulomatous Pyelonephritis
XGP Experimental Geosynchronous Platform
 (for Macintosh users) and testing them. However, AI::Prolog conveniently provides its own solution: by typing aiprolog at the command line, I can access a Prolog shell, load in my file, and run some tests.

At this point, however, I am mostly interested in accessing these rules from Perl. While there are several options for accessing Prolog from within Perl, the AI :: Prolog module is perhaps the easiest with which to start. Moreover, it is quite simple to use, the rules used to build the Prolog database being fed in when creating the AI : : Prolog object. The ability to hand the object constructor a filehandle is not currently supported, but would indeed be a nice improvement. While there are other ways to accomplish the task of reading in the data, such as calling the Prolog command consult, I will read in the Prolog file (ancentry.pl) and provide a string representation of the contents.

open ( PROLOGFILE, 'ancestry.pl' ) or die "$! \n"; local $/; my $prologRules = <PROLOGFILE>; close( PROLOGFILE );

my $prologDB = AI: :Prolog->new( $prologRules ) ;

Now that I have loaded my Prolog database, I need to feed it some more information. I need to take my data, in Dot format, and translate it into something that my Prolog interpreter will understand. There are some modules out there that may be helpful, such as DFA DFA - Deterministic Finite-state Automaton. See Finite State Machine. ::Simple, but since I can assume that my data will look a certain way--having written it from my other application--I will build my own simple parser A routine that analyzes a continuous flow of text-based input and breaks it into its constituent parts. See parse.

(language) parser - An algorithm or program to determine the syntactic structure of a sentence or string of symbols in some language.
. First, I am going to take a look at the data.

The visualization program created the diagram in Figure 1 from the code:

digraph family_tree {

  { jill [ color = pink ]
  rob [ color = blue ] } -> { ann [ color = pink ]
  joe [ color = blue ] ) ;

  { sue [ color = pink ]
  dan [ color = blue ] ) -> { sara [ color = pink ]
  mike [ color = blue ] } ;

  { nan [ color = pink ]
  tom [ color = blue ] } -> sue ;

  { nan
  jim [ color = blue ] } -> rob ;

  { kate [ color = pink ]
  steve [ color = blue ] } -> dan ;

  { lucy [ color = pink ]
  chris [ color = blue ] } -> jill ;


[FIGURE 1 OMITTED]

There are a few peculiarities worth mentioning here. First, it may seem that the all-lower-case names are a bit strange, but I am already preparing for the convention that data in Prolog is typically lower-case. Also, I inserted an extra space before the semicolons in an effort to make matching them easier. While both of these conventions are easy to code around, they seems to create extra questions when illustrating a point. Therefore, assume that the above Dot snippet A small amount of something. In the computer field, it often refers to a small piece of program code.  illustrates the range of possible formats in the example. While the "real-world examples" may provide a richer set of possibilities, the fact that applications with defined behavior generated this data will limit the edge cases.

Returning to the data, it will be easiest to parse the Dot data using a simple state machine. Previously, I had defined some constants to represent states:
use constant   { modInit => 0,
                 modTag  => 1,
                 modValue => 2 } ;


Basically, I assume that anything on the left-hand side left-hand side nizquierda

left-hand side left nlinke Seite f

left-hand side nlato or
 of the = is a parent and anything on me fight is a child. Additionally, modifies (in this case only color) begin with a left square-bracket and males have the blue modifier (programming) modifier - An operation that alters the state of an object. Modifiers often have names that begin with "set" and corresponding selector functions whose names begin with "get". , whereas females are pink. I know mat I have completed a parent-child relationship "block" when I hit me semicolon semicolon: see punctuation.


In programming, the semicolon (;) is often used to separate various elements of an expression. For example, in the C statement for (x=0; x<10; x++)
. Past these stipulations, if it isn't a character I know that I can safely ignore, then it must be a noun noun [Lat.,=name], in English, part of speech of vast semantic range. It can be used to name a person, place, thing, idea, or time. It generally functions as subject, object, or indirect object of the verb in the sentence, and may be distinguished by a number of .
sub parse_dotFile {

   ##--

   ## Examine data a word at a time

   ##--

   my @dotData = split( /\s+/, shift () ) ;

   my ( $familyBlock, $personName, @prologQry ) =   () ;
   my SpersonModPosition                        =   modInit;
   my Srelationship                             =   'parent';

   for ( my $idx = 3; $idx < @dotData; $idx++ ) {
   chomp( $dotData[$idx] );

   SWITCH: {

   ## ignore
   if ( SdotData[ $idx ] =~ /[{)=\]]/ ) {
   last SWITCH; }

   ## begin adding attributes
   if ( $dotData[ $idx ] eq '[' )
   SpersonModPosition = modTag;
   last SWITCH; }

   ## switch from parents to children
   if ( SdotData[ $idx ] eq '->' ) {
   Srelationship = 'child';
   last SWITCH; }

   ## end of this block
   if ( $dotData[ $idx ] =~ /\;/ ) {
   ##--

   ## Generate is_parent rules for Prolog

   ##--

   foreach my SparentInBlock ( @{ $familyBlock->{ parent } } ) {
   foreach my $childInBlock ( @{ $familyBlock->{ child } } ) {
   push( @prologQry,
   "is_parent(${parentInBlock}, ${childInBlock})" ) ;
   }
   }
   $familyBlock = () ;
   $relationship = 'parent';
   last SWITCH; }

   ## I have a noun, need to set something
   else {

   ## I have a modifier tag, next is the value
   if ( SpersonModPosition == modTag ) {
   $personModPosition = modValue;
   last SWITCH;

   } elsif ( SpensonModPosition == modValue ) {
   ## Set modifier value and reset
   ## We currently assume it is color
   ##
   if ( SdotData[ $idx ] eq 'blue' ) {

   push( @prologQry, "is male(${personName})" ) ;

   } else {
   push( @prologQry, "is_female(${personName}) " ) ;
   }
   $personModPosition = modInit;
   $personName        = () ;
   last SWITCH;
   else {
   ##--

   ## Grab the name and id as parent or child

   ##--
   $personName = SdotData[ $idx ];
   push( @{ $familyBlock->{ Srelationship } }, SpersonName );

   }
   }

   }

   }
   return (\@prologQry);
   }


Rather than simply pushing my new rules into the Prolog interpreter directly, I return an array that contains the full ruleset I am doing this so that I can easily dump it to a file for troubleshooting purposes. I can simply write the rules to a file, and consult this file in a Prolog shell.

With a subroutine A group of instructions that perform a specific task. A large subroutine might be called a "module" or "procedure." Subroutine is somewhat of a dated term, but it is still quite valid.  to parse my Dot file into Prolog rules, I can now push those rules into the interpreter:
   ##--
   ## Read in Dot file containing relations
   ## and feed it into the Prolog instance
   ##--
   open( DOTFILE, 'family tree.dot' ) or die "$! \n";
   my SparsedDigraph = parse_dotFile ( <DOTFILE> );
   close( DOTFILE ) ;

   foreach ( @$parsedDigraph ) {
      SprologDB->do ("assert ($_) . ") ;
   }

Now I can easily query my Prolog database using the query method in
AI : : Prolog:

   ##--
   ## Run the query
   ##--
   $prologDB->query( "is_cousin(joe, sara) ." );
   while (my $results = SprologDB->results) { print "@$results\n"; }


What Next?

Even though this is a trivial example, [ think that it provides an idea of the powerful ways in which Perl can be supplemented with Prolog. Just within the context of evaluating genealogical data (a mainstay of Prolog tutorials and examples), it seems that a Perl/Prolog application that uses genealogical data from open source genealogical software or websites would be a killer application Killer Application

Killer application or "killer app" is a buzzword that describes a software application that surpasses all of its competitors.

Notes:
The term is sometimes used to describe a type of software.
. The possibilities seem endless: rules based Using "if-this, do that" rules to perform actions. Rules-based products implies flexibility in the software, enabling tasks and data to be easily changed by replacing one or more rules.  upon Google maps Google Maps (for a time named Google Local) is a free web mapping service application and technology provided by Google that powers many map-based services including the Google Maps website, Google Ride Finder and embedded maps on third-party websites via the Google Maps , mining information from online auctions or news services, or even harvesting information for that new test harness In software testing, a test harness or automated test framework is a collection of software and test data configured to test a program unit by running it under varying conditions and monitor its behavior and outputs.  are all tremendous opportunities for the marriage of Perl and Prolog.
COPYRIGHT 2006 A.P. Publications Ltd.
No portion of this article can be reproduced without the express written permission from the copyright holder.
Copyright 2006, Gale Group. All rights reserved. Gale Group is a Thomson Corporation Company.

 Reader Opinion

Title:

Comment:



 

Article Details
Printer friendly Cite/link Email Feedback
Title Annotation:DATABASE AND NETWORK INTELLIGENCE
Author:Pratte, Robert
Publication:Database and Network Journal
Date:Apr 1, 2006
Words:1665
Previous Article:Obscene kama sutra worm spreads via mail.(Security)
Next Article:Integrated managed service for instant messaging and web security.



Related Articles
Kristalia: The Bebop bookshelf. (Product Review).(Brief Article)(Product Announcement)
Seeing in the Dark: How Backyard Stargazers Are Probing Deep Space and Guarding Earth from Interplanetary Peril.(Book Review)
"Perl for Oracle DBAS". (Database News and Products).
PROFESSIONAL PROJECT MANAGEMENT TOOL CONSOLIDATES DOCUMENTS.
Deception.(Brief Article)(Young Adult Review)(Audiobook Review)
How to program a domain independent tracer for explanations.
The International Academy of Digital Arts and Sciences has honored the Web site for BeBop Apparel with The Webby Award for the "Best Use of Animation...
Answers to common questions about AI.(ARTIFICIAL INTELLIGENCE PART 1)
Sunny side heads up.(LETTERS)(Letter to the editor)
Fire at Nash skateboard factory.(AWFUL TRUTH)

Terms of use | Copyright © 2009 Farlex, Inc. | Feedback | For webmasters | Submit articles