Pattern

From Dyna

Jump to: navigation, search

relvie cataortro racaloloelt relvin alzelnogetge delletova lic4tc racmono Warning: Not implemented yet. However, you can use queries in the current version.

Contents

What is a pattern?

A pattern is like a term except that some of its subterms may be variables. For example, in an inference rule like

pathto(V) min= pathto(U)+edge(U,V).

the consequent pathto(V) is an item pattern, and the antecedent is an expression pattern. When a Dyna program runs, it does a lot of pattern matching.

As an advanced feature, you can also specify patterns directly

  • to create subtypes (as usual, strong typing is both safer and more efficient)
  • to specify program transformations (in which the pattern is replaced by a specialized structure type, for efficiency)
  • to enable the C++ driver program to

Declaring patterns

You can declare patterns in a Dyna program as follows.

:- pattern(mypattern, constit(np,I,I)).
:- pattern(lengthtwo, edge(U,V)+edge(V,W)).
:- pattern(deep, foo(X,Y,yada(yada(yada(X))))).

Some patterns are automatically declared for you. The inference rule shown earlier, pathto(V) min= pathto(U)+edge(U,V), results in the following automatic declarations of antecedent and consequent patterns. These are used as the return types of the antecedent and consequent iterators. For example, if you ask for the antecedents of a particular pathto item, then you will get back an iterator over terms of type pathto::antecedent.

:- pattern('pathto::antecedent', pathto(U)+edge(U,V)).
:- pattern('pathto::consequent', pathto(V)).
:- pattern('edge::consequent', pathto(V)).
Only antecedent patterns are implemented so far.

Patterns as subtypes

Just as a union declaration creates a new supertype, a pattern declaration creates a new subtype. Thus, once mypattern is declared, you can use it like other types:

:- structure(foo(mypattern p)).
:- union(bar,[mypattern,string]).

so that foo(constit(np,5,5)) is a legal term but foo(constit(s,0,8)) is not. Note that mypattern is a subtype of both constit (a structure type) and bar (a union type).

Similarly, pathto::antecedent is a subtype of expr_double (an expression type). (Assuming that pathto is a subtype of item_double, i.e., has been declared with :- item(pathto,double,0).)

Like structure types, pattern types have constructors. The constructor arguments are the variable bindings, in order of first (leftmost) mention. Thus, given the declarations from above,

:- pattern(mypattern, constit(np,I,I)).
:- pattern(lengthtwo, edge(U,V)+edge(V,W)).
:- pattern(deep, foo(X,Y,yada(yada(yada(X))))).

you can write

mypattern(5)                 % constit(np,5,5)
lengthtwo("a","b","c")       % edge("a","b")+edge("b","c")
deep([1,2],3)                % foo([1,2],3,yada(yada(yada([1,2]))))

Note that what you are constructing is not a pattern (which is a type), but a term matching that pattern (which is an instance of the type).

Patterns with type restrictions

You can restrict a pattern by specifying types for its variables. For example,

:- structure(foo(int i, list l)).
:- pattern(zerolist, foo(0,L)).  
:- pattern(zerocons, foo(0,cons L))).  

Now zerocons is a subtype of zerolist, which in turn is a subtype of foo. Both foo(0,[]) and foo(0,[3,4]) are zerolists, but only the latter is a zerocons.

As an alternative, zerocons can be defined as a pattern that matches against the one-argument zerolist constructor:

:- pattern(zerocons, zerolist(cons L)).   % equivalent to previous definition

Circular declarations using patterns

As with unions, circular declarations are allowed. Here is an ordinary binary tree type that stores an element at each leaf (external node) and each branch (internal node):

:- union(tree,[leaf,branch]).
:- structure(leaf(term element)).  
:- structure(branch(term element, tree left, tree right)).

Using patterns, we can define symmetric trees, in which the left branch equals the right branch:

:- union(symmtree,[leaf,symmbranch]).
:- pattern(symmbranch, branch(Element, symmtree Subtree, symmtree Subtree)).

In other words, a symmetric tree is either a leaf, or a branch whose left and right children are equal symmetric trees. symmtree is a subtype of tree, but the compiler can take advantage of the restrictions to store and process it more efficiently than an arbitrary tree.

Note that the following constructors can be used:

symmbranch(1,symmbranch(2,leaf(3)))  % yields branch(1,branch(2,leaf(3),leaf(3)),
                                                       branch(2,leaf(3),leaf(3)))
symmtree(1,symmtree(2,symmtree(3))) %
Retrieved from "http://www.dyna.org/Pattern"
Personal tools