{"id":263,"date":"2016-06-17T10:08:28","date_gmt":"2016-06-17T10:08:28","guid":{"rendered":"http:\/\/www.rangakrish.com\/?p=263"},"modified":"2016-06-17T10:10:23","modified_gmt":"2016-06-17T10:10:23","slug":"pattern-matching-with-optima-lisp-library-part-2","status":"publish","type":"post","link":"https:\/\/www.rangakrish.com\/index.php\/2016\/06\/17\/pattern-matching-with-optima-lisp-library-part-2\/","title":{"rendered":"Pattern Matching with Optima Lisp Library &#8211; Part 2"},"content":{"rendered":"<p>Let us continue where we left off last time.<\/p>\n<h2>List Patterns<\/h2>\n<p>If the incoming argument is a list, then we can use two types of list patterns to match the list elements, namely, <strong>list<\/strong> and <strong>list*<\/strong>.<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list &#8216;a &#8216;b X) X))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; c<\/strong><\/em><\/p>\n<p>This list pattern begins with the <strong>list<\/strong> keyword. After that you can specify either the actual elements in the list or variables. If a variable is specified, it will match exactly one element of the list. In this example, we expect two elements \u2018a and \u2018b followed by any element. As expected, the variable <strong>X<\/strong> matches the element <strong>c<\/strong> in the argument.<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list &#8216;a &#8216;b X) (print X)))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; nil<\/strong><\/em><\/p>\n<p>Here the pattern looks for a 3 element list, and so it fails.<\/p>\n<p>You can use the convenient backquote mechanism for list matching:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>(`(a b ,x) x))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; c<\/strong><\/em><\/p>\n<p>This saves a few keystrokes and makes it more readable. Note that you have to use the comma before a variable to mark it as a variable.<\/p>\n<p>The second type of list pattern uses the keyword <strong>list*<\/strong>. It allows the use of variables as in the other type, but the last variable will match multiple elements of the incoming list.<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c d)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* &#8216;a &#8216;b X ) X))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; (c d)<\/strong><\/em><\/p>\n<p>You can see that variable <strong>X<\/strong> matches the last 2 elements of the argument.<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c d)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* X &#8216;b &#8216;c Y) Y))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; (d)<\/strong><\/em><\/p>\n<p>Here we have 2 variables and <strong>Y<\/strong> matches the last (trailing) arguments. Consider this case:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c d)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* &#8216;a &#8216;b &#8216;c &#8216;d X ) t))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p>Here the variable X will be bound to an empty list. You can replace a variable by an underscore if you don\u2019t need the binding:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c d)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* &#8216;a &#8216;b &#8216;c &#8216;d _ ) t))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p>Consider the following examples of an empty list as supplied argument:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;()\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* _) t)) ;<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;()\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>((list* X) t))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p>We can use backquote as we did earlier, with a slight difference:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(a b c d)\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 60px;\"><em><strong>(`(a b ,@x) x))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; (c d)<\/strong><\/em><\/p>\n<p><strong>&#8220;,@&#8221;<\/strong> denotes a list, since this is a multi-value match.<\/p>\n<p>It is worthwhile to\u00a0 compare <strong>list<\/strong> and <strong>list*<\/strong> patterns using a common example:<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(p q r s)<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((list &#8216;p &#8216;q &#8216;r &#8216;s) t))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(p q r s)<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((list* &#8216;p &#8216;q &#8216;r &#8216;s) t))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; nil<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(p q r s)<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((list* &#8216;p &#8216;q &#8216;r (list &#8216;s)) t))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; t<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;(p q r s)<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((list* &#8216;p &#8216;q &#8216;r x) x))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; (s)<\/strong><\/em><\/p>\n<p>Notice how <strong>list*<\/strong> has the last element as a list.<\/p>\n<h2>Property Lists<\/h2>\n<p>If you have a list of <strong>key<\/strong> and <strong>value<\/strong> pairs, then you can use the <strong>plist<\/strong> pattern to match the same.<\/p>\n<p><em><strong>(match &#8216;(:name &#8220;Peter&#8221; :age 45 :gender &#8220;Male&#8221; :country &#8220;India&#8221;)<\/strong><\/em><\/p>\n<p><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((plist :name N :gender G :age A) (list N G A)))<\/strong><\/em><\/p>\n<p><em><strong>=&gt; (&#8220;Peter&#8221; &#8220;Male&#8221; 45)<\/strong><\/em><\/p>\n<p>Notice that the order is not important here, and you can match any subset.<\/p>\n<h2>Assoc Lists<\/h2>\n<p>Optima supports pattern matching in assoc lists, as in list of pairs. See the following examples.<\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;((a . 1) (b . 2) (c . 3))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((assoc b x) x))\u00a0<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; 2<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;((a . 1) (b . 2) (c . 3))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((and (assoc a x) (assoc b y) (assoc c 3)) (+ x y)))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; 3<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;((a 1) (b 2) (c 3))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((and (assoc a x) (assoc b y) (assoc c z)) (list x y z)))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; ((1) (2) (3))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>(match &#8216;((a 1) (b 2) (c 3))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>\u00a0\u00a0 \u00a0 \u00a0 ((and (assoc a (list x)) (assoc b (list y)) (assoc c (list z))) (list x y z)))<\/strong><\/em><\/p>\n<p style=\"padding-left: 30px;\"><em><strong>=&gt; (1 2 3)<\/strong><\/em><\/p>\n<p>Hope you can see the difference between using a dotted pair versus a 2-element list.<\/p>\n<p>We have covered quite a bit\u00a0in this post, and it is time to take a break. In the next post, I will show how\u00a0to apply these ideas in Opusmodus.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Let us continue where we left off last time. List Patterns If the incoming argument is a list, then we can use two types of list patterns to match the list elements, namely, list and list*. (match &#8216;(a b c)\u00a0 ((list &#8216;a &#8216;b X) X)) =&gt; c This list pattern begins with the list keyword. [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[18,17],"tags":[61,62],"class_list":["post-263","post","type-post","status-publish","format-standard","hentry","category-lisp","category-programming","tag-optima","tag-pattern-matching"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p9OLnF-4f","jetpack-related-posts":[{"id":256,"url":"https:\/\/www.rangakrish.com\/index.php\/2016\/06\/09\/pattern-matching-with-optima-lisp-library\/","url_meta":{"origin":263,"position":0},"title":"Pattern Matching with Optima Lisp Library","author":"admin","date":"June 9, 2016","format":false,"excerpt":"In the previous two posts, we looked at external tools and libraries that can be used along with Opusmodus for algorithmic composition. In this post, I want to introduce\u00a0another interesting Lisp library called Optima. Optima is a powerful library for pattern matching. Often, when we talk of pattern matching, the\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":268,"url":"https:\/\/www.rangakrish.com\/index.php\/2016\/06\/29\/pattern-matching-with-optima-lisp-library-part-3\/","url_meta":{"origin":263,"position":1},"title":"Pattern Matching with Optima Lisp Library &#8211; Part 3","author":"admin","date":"June 29, 2016","format":false,"excerpt":"In the previous two posts on this topic, I explained some of the basic pattern matching facilities of Optima\u00a0library. There are many\u00a0more advanced features in the library and I will try to discuss them in future posts. In today\u2019s post, I will outline a straightforward application of the library for\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"Optima Example","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/06\/Optima-Example-1024x622.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/06\/Optima-Example-1024x622.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/06\/Optima-Example-1024x622.png?resize=525%2C300 1.5x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2016\/06\/Optima-Example-1024x622.png?resize=700%2C400 2x"},"classes":[]},{"id":2084,"url":"https:\/\/www.rangakrish.com\/index.php\/2020\/08\/16\/pattern-matching-comparing-elixir-and-mathematica\/","url_meta":{"origin":263,"position":2},"title":"Pattern Matching: Comparing Elixir and Mathematica","author":"admin","date":"August 16, 2020","format":false,"excerpt":"One of the things I like about Elixir\u00a0is its support for patterns at the core language level, not through library functions as in most other languages. This contributes to writing cleaner code, in my opinion. \u00a0 Another environment that I am familiar with, namely Mathematica, boasts of (arguably) the most\u2026","rel":"","context":"In &quot;Elixir&quot;","block_context":{"text":"Elixir","link":"https:\/\/www.rangakrish.com\/index.php\/category\/elixir\/"},"img":{"alt_text":"Symbolic Expressions","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/08\/pattern-mm.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/08\/pattern-mm.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2020\/08\/pattern-mm.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":2620,"url":"https:\/\/www.rangakrish.com\/index.php\/2021\/11\/28\/understanding-the-unify-function-in-newlisp\/","url_meta":{"origin":263,"position":3},"title":"Understanding the &#8220;unify&#8221; Function in &#8220;newLisp&#8221;","author":"admin","date":"November 28, 2021","format":false,"excerpt":"Unification between two symbolic expressions involves finding substitutions for variables (if any) in the expressions such that the expressions match\u00a0after applying the substitutions. This is a powerful idea and is quite common in logic programming languages such as Prolog. Interestingly, \"newLisp\" has a buil-in function called \"unify\" that can be\u2026","rel":"","context":"In &quot;newLisp&quot;","block_context":{"text":"newLisp","link":"https:\/\/www.rangakrish.com\/index.php\/category\/newlisp\/"},"img":{"alt_text":"Unifying \"atomic\" expressions","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/11\/Example1-1-300x106.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2593,"url":"https:\/\/www.rangakrish.com\/index.php\/2021\/11\/01\/implicit-indexing-and-slicing-in-newlisp\/","url_meta":{"origin":263,"position":4},"title":"Implicit Indexing and Slicing in &#8220;newLisp&#8221;","author":"admin","date":"November 1, 2021","format":false,"excerpt":"In traditional Lisp (Common Lisp), when evaluating an S-expression list, the first element in the \"functor\" position must be a function or valid operator. newLisp\u00a0relaxes this requirement and allows the first element to be a context symbol type, a list, an array, or an integer. For today's discussion, let us\u2026","rel":"","context":"In &quot;newLisp&quot;","block_context":{"text":"newLisp","link":"https:\/\/www.rangakrish.com\/index.php\/category\/newlisp\/"},"img":{"alt_text":"List Indexing","src":"https:\/\/i0.wp.com\/www.rangakrish.com\/wp-content\/uploads\/2021\/11\/list1-300x141.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":558,"url":"https:\/\/www.rangakrish.com\/index.php\/2017\/07\/07\/clpython-python-in-common-lisp\/","url_meta":{"origin":263,"position":5},"title":"CLPython &#8211; Python in Common Lisp","author":"admin","date":"July 7, 2017","format":false,"excerpt":"My work in the area of NLP requires\u00a0me to work with several frameworks across multiple languages such as Java, Python and Lisp. Sometime ago I got a chance to experiment with CLPython, an open-source implementation of Python in Common Lisp. Although CLPython is not under active development now, I found\u2026","rel":"","context":"In &quot;LISP&quot;","block_context":{"text":"LISP","link":"https:\/\/www.rangakrish.com\/index.php\/category\/lisp\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"_links":{"self":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/263","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/comments?post=263"}],"version-history":[{"count":0,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/posts\/263\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/media?parent=263"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/categories?post=263"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rangakrish.com\/index.php\/wp-json\/wp\/v2\/tags?post=263"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}