|
| 1 | +<?xml version="1.0" encoding="UTF-8"?> |
| 2 | +<?xml-stylesheet type="text/xsl" href="../../interface/layout.xsl"?> |
| 3 | +<page> |
| 4 | +<filename>Declarative/Data-Simple-Queries.xml</filename> |
| 5 | +<sitedir>Metanoias</sitedir> |
| 6 | +<content> |
| 7 | + |
| 8 | +<h1>Predicate and Laws: Multi functions/methods in reverse</h1> |
| 9 | + |
| 10 | +<h3>Conceptual</h3> |
| 11 | + |
| 12 | +<p><i>Predicates and laws are multi functions in reverse</i></p> |
| 13 | + |
| 14 | +<p>In a function call, you provide <i>data</i> which are matched against the |
| 15 | +<i>criteria</i> in the function definition. If they match, then the body of |
| 16 | +the function is executed. </p> |
| 17 | + |
| 18 | +<p>In a query, you provide <i>criteria</i> which are matched against the |
| 19 | +<i>data</i> in the table/database. If they match, the relevant data records are |
| 20 | +returned</p> |
| 21 | + |
| 22 | +<h3>Raku</h3> |
| 23 | + |
| 24 | +<p><i>Predicates are the reverse of proto. Laws are the reverse of the multi candidates.</i></p> |
| 25 | + |
| 26 | +<p>In a <i>method call</i>, you provide a <code>Capture</code> which is matched |
| 27 | +against the <code>Signature</code> in the method definition. If they |
| 28 | +match, the variables are bound, and the function body is run, returning |
| 29 | +a return value. </p> |
| 30 | + |
| 31 | +<p>In a <i>query</i>, you provide a <code>Signature</code> which is matched |
| 32 | +against the <code>Capture</code> or <code>Signature</code> provided in the |
| 33 | +<code>law</code>s specified in the predicate (which is in a database). </p> |
| 34 | + |
| 35 | + |
| 36 | +<h2>Laws: Data for a Predicate</h2> |
| 37 | + |
| 38 | +<p>When you define a law, |
| 39 | +you specify values for the parameters (and it's a multi, so multiple law |
| 40 | +defintions within the predicate are likely). This makes the parameter |
| 41 | +definition more like a Capture than a Signature. When you run a query (ie. |
| 42 | +make a call to a law/predicate), you use a Signature in the query, and it |
| 43 | +returns all the definitions that matched. This makes it useful for queries |
| 44 | +-- you can put in a query with some undefined (free) variables and it will return all |
| 45 | +items (Laws) that match. </p> |
| 46 | + |
| 47 | +<p>The matching logic (traditionally called "unification") is almost exactly |
| 48 | +what's used for Multiple Dispatch, with the exception that, when a definition |
| 49 | +matches, the body is run (and this is where the power of this approach comes |
| 50 | +from). The body will return a Match object; if the Match object evaluates to |
| 51 | +True, the Match is added to the array of return values. </p> |
| 52 | + |
| 53 | +<p>Here's a comparison table:</p> |
| 54 | + |
| 55 | +<table> |
| 56 | + <tr> |
| 57 | + <th>Item</th> |
| 58 | + <th>Function Definition</th> |
| 59 | + <th>Function Call</th> |
| 60 | + <th>Law (aka Law Definition)</th> |
| 61 | + <th>Query (aka Law Call)</th> |
| 62 | + </tr> |
| 63 | + <tr><th colspan="5">Routine Parts</th></tr> |
| 64 | + <tr> |
| 65 | + <th>Routine Name</th> |
| 66 | + <td>Identifier</td> |
| 67 | + <td>Identifier</td> |
| 68 | + <td>Identifier</td> |
| 69 | + <td>Identifier</td> |
| 70 | + </tr> |
| 71 | + <tr> |
| 72 | + <th>Routine Inputs</th> |
| 73 | + <td>Signature</td> |
| 74 | + <td>Capture</td> |
| 75 | + <td>Capture</td> |
| 76 | + <td>Signature</td> |
| 77 | + </tr> |
| 78 | + <tr> |
| 79 | + <th>Routine Outputs</th> |
| 80 | + <td colspan="2">Return Value + rw Parameters</td> |
| 81 | + <td colspan="2">Match Object</td> |
| 82 | + </tr> |
| 83 | + <tr> |
| 84 | + <th>Routine Body</th> |
| 85 | + <td>Raku Code Block</td> |
| 86 | + <td>-</td> |
| 87 | + <td>Raku Law Code Block</td> |
| 88 | + <td>-</td> |
| 89 | + </tr> |
| 90 | + <tr><th colspan="5">Matching process</th></tr> |
| 91 | + <tr> |
| 92 | + <th>Overview</th> |
| 93 | + <td colspan="2">Take a single Capture (in call), and compare against each |
| 94 | + available signature (in definition)</td> |
| 95 | + <td colspan="2">Take a single Signature (in call), and compare against |
| 96 | + each available Capture/Signature (in definition)</td> |
| 97 | + </tr> |
| 98 | + <tr> |
| 99 | + <th>Stop matching after</th> |
| 100 | + <td colspan="2">First match</td> |
| 101 | + <td colspan="2">All that match (ie. each function has an implied "nextsame" at the end)</td> |
| 102 | + </tr> |
| 103 | +</table> |
| 104 | + |
| 105 | +<h3>Reversal of Capture and Signature</h3> |
| 106 | + |
| 107 | +<p>The first thing to note in the table above is the reversing of the |
| 108 | +Signature and the Capture. A Capture has the values filled in already, and |
| 109 | +the Signature is full of named unknowns (free variables) where the values can |
| 110 | +be put (if binding succeeds). In this case, Law calls will be |
| 111 | +used in the Query, so they are full of unknowns (Signature) that want to match |
| 112 | +something (Capture). As per the "role BirthdayCongrats" example near the |
| 113 | +bottom of <a href="https://docs.raku.org/syntax/multi">multi</a>, it's already |
| 114 | +possible for a Signature to contain actuals as well, which will need to match |
| 115 | +the actuals in the Capture as well. </p> |
| 116 | + |
| 117 | +<h3>Multiple Bindings</h3> |
| 118 | + |
| 119 | +<p>The second thing to note is that in both cases, the binding process takes the |
| 120 | +call, and matches it against the definition looking for matches, but functions |
| 121 | +will execute the first match, and just return that value, whereas in the |
| 122 | +case of queries, it executes every law that matches, not just the first. </p> |
| 123 | + |
| 124 | +<h3>Law bodies</h3> |
| 125 | + |
| 126 | +<p>Naturally, the body of this kind of routine can't be quite like the body |
| 127 | +of a regular routine. The relevant changes are:</p> |
| 128 | + |
| 129 | +<ul> |
| 130 | + <li>Any code called should be predicates/queries, not other kinds of routine</li> |
| 131 | + <li>The law should return a Match object that is true if the item matches, |
| 132 | + and false if not. </li> |
| 133 | + <li>If no body is supplied, the default is to return a Match that's the same |
| 134 | + as the Capture in the law specification, and also Match.Bool returns |
| 135 | + True</li> |
| 136 | +</ul> |
| 137 | + |
| 138 | +<h2>The Family Tree Example</h2> |
| 139 | + |
| 140 | +<p>Now for an example. To see the family tree modelled here as a diagram, see |
| 141 | +<a href="https://www.chegg.com/homework-help/questions-and-answers/consider-following-family-tree-represent-family-tree-prolog-define-cousin-relationship-not-q52199342"> |
| 142 | +Family Tree Question</a>. </p> |
| 143 | + |
| 144 | +<p>First, let's look at the initial setup of the database:</p> |
| 145 | +<code class="block"># A Database is a group of predicates/laws, just as a class is a group of methods and attributes |
| 146 | +database Kinships { |
| 147 | + # Declare a proto for fatherOf -- could use objects instead of strings |
| 148 | + predicate fatherOf(Str $name, Str $fathersname); |
| 149 | + law fatherOf("Alex", "John"); |
| 150 | + law fatherOf("Bob", "John"); |
| 151 | + law fatherOf("Mick", "Alex"); |
| 152 | + ... |
| 153 | +} |
| 154 | +</code> |
| 155 | +<p>In the above, we can see that the predicate called <code>fatherOf</code> |
| 156 | +says that it returns pairs of strings with the field names <code>$name</code> |
| 157 | +and <code>$fathersname</code>. </p> |
| 158 | + |
| 159 | +<p>As instances of the predicate, we can see three <code>fatherOf</code> laws |
| 160 | +being declared. </p> |
| 161 | + |
| 162 | +<p>The laws have Captures, and the predicate has a Signature. The return |
| 163 | +values of the laws are Match classes that evaluate to True, and have the data |
| 164 | +from the Capture in them. This means that when the predicate is queried, |
| 165 | +the Captures will be returned. </p> |
| 166 | + |
| 167 | +<p>Now that we've declared our data, the question is how to query it. </p> |
| 168 | + |
| 169 | +<code class="block"># A query |
| 170 | +say Kinships.fatherOf(Str $name, "John").raku; |
| 171 | +# OUTPUT: |
| 172 | +# «[ |
| 173 | +# Match.new(name => "Alex", fathersname => "John"), |
| 174 | +# Match.new(name => "Bob", fathersname => "John") |
| 175 | +# ]» |
| 176 | +</code> |
| 177 | + |
| 178 | +<p>We can see that the query has is a Signature, which matches the Signature |
| 179 | +in the predicate, and some of the Captures in the laws, but not all of them. |
| 180 | +</p> |
| 181 | + |
| 182 | +<p>So far, nothing that special; the special sauce comes from the accretion |
| 183 | +of all the declarative features. </p> |
| 184 | + |
| 185 | + |
| 186 | +<h1>Comparitive Terminology</h1> |
| 187 | + |
| 188 | +<p>If you're familiar with one of the following fields, the following table |
| 189 | +may be helpful; if not, just skip it. </p> |
| 190 | + |
| 191 | +<table> |
| 192 | + <tr> |
| 193 | + <th>Declaraku</th> |
| 194 | + <th>SQL.</th> |
| 195 | + <th>Relation Algebra</th> |
| 196 | + <th>Logic Programming</th> |
| 197 | + <th>XML</th> |
| 198 | + </tr> |
| 199 | + <tr> |
| 200 | + <td>database</td> |
| 201 | + <td>Database</td> |
| 202 | + <td>Database</td> |
| 203 | + <td>(database)</td> |
| 204 | + <td>Document</td> |
| 205 | + </tr> |
| 206 | + <tr> |
| 207 | + <td>predicate</td> |
| 208 | + <td>Table-Type Declaration (cf. PostgreSQL Type declaration)</td> |
| 209 | + <td>Relation</td> |
| 210 | + <td>Predicate</td> |
| 211 | + <td>-</td> |
| 212 | + </tr> |
| 213 | + <tr> |
| 214 | + <td>Law (or query result?)</td> |
| 215 | + <td>Record</td> |
| 216 | + <td>Tuple</td> |
| 217 | + <td>rule/fact</td> |
| 218 | + <td>Element</td> |
| 219 | + </tr> |
| 220 | + <tr> |
| 221 | + <td>Query</td> |
| 222 | + <td>Query</td> |
| 223 | + <td></td> |
| 224 | + <td>Query</td> |
| 225 | + <td>Query</td> |
| 226 | + </tr> |
| 227 | + <tr> |
| 228 | + <td></td> |
| 229 | + <td></td> |
| 230 | + <td></td> |
| 231 | + <td></td> |
| 232 | + <td></td> |
| 233 | + </tr> |
| 234 | +</table> |
| 235 | + |
| 236 | + |
| 237 | + |
| 238 | +<h1>Predicates and Joins</h1> |
| 239 | + |
| 240 | +<h2>Overview</h2> |
| 241 | + |
| 242 | +<p>A Predicate is a descendent of Set (or maybe does Set), but also of proto |
| 243 | +methods. The Predicate has an attached Signature (ie. a list of names with |
| 244 | +types, but no bound variables). The elements of the Predicate are items that |
| 245 | +do Callable (mostly laws -- see below). This means that each |
| 246 | +element will have a Capture method. They should only be placed in the set if |
| 247 | +that Capture matches the Signature of the Predicate. </p> |
| 248 | + |
| 249 | +<p>Predicates function as Relations (with a few additional pieces). </p> |
| 250 | + |
| 251 | + |
| 252 | +</content> |
| 253 | +</page> |
0 commit comments