| … | … | @@ -88,25 +88,114 @@ |
| 88 | 88 | (List x))) |
| 89 | 89 | |
| 90 | 90 | ; -------------------------------------------------------------- |
| 91 | | ; Create a filter that will extract just the edges from the compund |
| 92 | | ; stream demoed above. This filter will ignore the list of words, |
| 93 | | ; and will iterate over the list of edges. |
| 91 | ; Create a filter that will extract just the edges from the compound |
| 92 | ; stream generated by the parser. The end-goal of this filter is to |
| 93 | ; ignore the list of words, and will iterate over the list of edges. |
| 94 | 94 | ; |
| 95 | ; Build this up in a sequence of stages. First, a demo of the FilterLink |
| 96 | ; combined with the RuleLink. The FilterLink is analogous to the srfi-1 |
| 97 | ; filter: it takes a pattern P and a list L and discards everything in |
| 98 | ; the list that does not match the pattern P. |
| 99 | ; |
| 100 | ; The FilterLink allows an optional variable list, so that P(x,y,z) |
| 101 | ; specifies a pattern P with variable portions x,y,z. If the input |
| 102 | ; matches the pattern P(x,y,z), then the output of the filter is (x,y,z). |
| 103 | ; That is, the filter acts as an extractor of pieces-parts. It is a |
| 104 | ; disassembler of the input stream. |
| 105 | ; |
| 106 | ; See https://wiki.opencog.org/w/FilterLink |
| 107 | ; |
| 108 | ; The RuleLink specifies a rewrite rule P->Q. Given some input pattern P, |
| 109 | ; it picks apart the contents of P and generates Q as output. That is, |
| 110 | ; it specifies a mapping function from things that look like P to things |
| 111 | ; Q made out of the parts of P. It is called a rule, because it is used |
| 112 | ; in other places to implement logical implication. |
| 113 | ; |
| 114 | ; The RuleLink has an optional variable declaration, so that the rules |
| 115 | ; can be understood as P(x,y,z)->Q(x,y,z) where the components x,y,z |
| 116 | ; are picked out of the pattern P and are then used to build Q. |
| 117 | ; |
| 118 | ; See https://wiki.opencog.org/w/RuleLink |
| 119 | ; |
| 120 | ; The combination of Filter+Rule is analogous to the srfi-1 filter-map, |
| 121 | ; so that the rewrite P->Q is applied to all the elements in the list L. |
| 122 | ; |
| 123 | ; The main difficulty in using all this is a need to unwrap all the |
| 124 | ; stuff coming out of the parser, to get at exactly the part that we |
| 125 | ; want. |
| 126 | |
| 127 | ; Step one: (Glob "$x") matches everything. So, the first demo is |
| 128 | ; a no-op, except that it maps the entire result with one more LinkValue |
| 129 | ; (because Globs do that, to list everythig that was globbed together.) |
| 130 | |
| 131 | (define demo-filter |
| 132 | (Filter |
| 133 | (Glob "$x") |
| 134 | (LgParseBonds (Phrase "this is a test") (LgDict "any") (Number 1)))) |
| 135 | |
| 136 | ; Run it. |
| 137 | (cog-execute! demo-filter) |
| 138 | |
| 139 | ; Same as above, but with a no-op rule |
| 140 | (define demo-filter |
| 141 | (Filter |
| 142 | (Rule |
| 143 | (Glob "$x") ; Input |
| 144 | (Glob "$x")) ; Output |
| 145 | (LgParseBonds (Phrase "this is a test") (LgDict "any") (Number 1)))) |
| 146 | |
| 147 | ; Run it. |
| 148 | (cog-execute! demo-filter) |
| 149 | |
| 150 | ; Same as above, but now start matching stuff inside the stream. |
| 151 | ; This is still an almost trivial no-op; but it does unwrap one |
| 152 | ; layer of LinkValue. |
| 153 | (define demo-filter |
| 154 | (Filter |
| 155 | (Rule |
| 156 | ; Match clause - one per parse. |
| 157 | (LinkSignature |
| 158 | (Type 'LinkValue) |
| 159 | (Glob "$stuff")) |
| 160 | |
| 161 | ; Output |
| 162 | (Glob "$stuff")) |
| 163 | |
| 164 | (LgParseBonds (Phrase "this is a test") (LgDict "any") (Number 1)))) |
| 165 | |
| 166 | ; Run it. |
| 167 | (cog-execute! demo-filter) |
| 168 | |
| 169 | ;Pair |
| 170 | (define demo-filter |
| 171 | (Filter |
| 172 | (Rule |
| 173 | ; Match clause - one per parse. |
| 174 | (LinkSignature |
| 175 | (Type 'LinkValue) |
| 176 | (Glob "$stuff")) |
| 177 | |
| 178 | ; Output |
| 179 | (Glob "$stuff")) |
| 180 | |
| 181 | (LgParseBonds (Phrase "this is a test") (LgDict "any") (Number 1)))) |
| 182 | |
| 183 | ; Run it. |
| 184 | (cog-execute! demo-filter) |
| 185 | |
| 95 | 186 | |
| 96 | 187 | (define edge-filter |
| 97 | 188 | (Filter |
| 98 | 189 | (Rule |
| 99 | | ; Type decl |
| 100 | | (Glob "$x") |
| 101 | 190 | ; Match clause - one per parse. |
| 102 | 191 | (LinkSignature |
| 103 | | (Type 'LinkValue) ; the wrapper for the pair |
| 192 | (Type 'LinkValue) ; type of (vertex,edge) pair |
| 104 | 193 | (Type 'LinkValue) ; the word-list |
| 105 | 194 | (LinkSignature ; the edge-list |
| 106 | 195 | (Type 'LinkValue) ; edge-list wrapper |
| 107 | 196 | (Glob "$edge-list"))) ; all of the edges |
| 108 | 197 | ; Pipeline to apply to the resulting match. |
| 109 | | (count-edges (Glob "$edge-list")) |
| 198 | (debug-prt (Glob "$edge-list")) |
| 110 | 199 | ) |
| 111 | 200 | (LgParseBonds (Phrase "this is a test") (LgDict "any") (Number 1)))) |
| 112 | 201 | |