Showing posts with label surprise. Show all posts
Showing posts with label surprise. Show all posts

Wednesday, 1 August 2007

Restricting the search scope to improve performance

One major issue with DeepWeaver is that any call that results in the body predicate executing results in substantial slowdown, particularly upon a large code base. Predicates that result in body being called include call(x,y,z) and assign(x,y,z) when x is a free variable.

In both cases here, x represents a statement, and without that statement being bound, the body predicate must be called to traverse all Units in the codebase to check whether it matches your criteria. This can be particularly slow if the matching criteria itself is expensive.

Remember DeepWeaver doesn't just analyse the class or package you specified, if you call an unbound assign or call predicate it will dive into the libraries and look for results. This includes looking through classes such as Object and Throwable from which common Java features are derived. Needless to say, it's going to slow you down.

At time of writing there's no artificial predicate to limit the scope based on what is specified in your command line, but there's an easy way to do this manually.
If you want to restrict yourself to a certain class or set of classes, simply specify:
scope(u)=class(c,"org.owasp.webgoat.session.User*"), units(body(sootmethod(c,<-),<-),u);

and then
scope(u), assign(u,y,z), ...

and now the first predicate in assign is bound to be a unit from some class beginning with User in the specified package. This dramatically restricts the scope of possible values for u and thus greatly improves the resulting performance.

Notice the use of wildcards here, you may use wildcards in both the class and package name but you must attempt to specify the class name to some degree. So you could say org.owasp.*.User* to find your classes, or ever org.*.* but that dot is essential to include, or it will assume your package to be a class name and fail to find the result you're looking for.

Thursday, 19 July 2007

Predicate Specification

A couple of notes on how to specify your predicates in DeepWeaver, that are worth mentioning because they're different from how they're specified in Prolog.

When you're specifiying a predicate there are a number of reserved keywords, and an few restrictions.
name(fn,sn)=getName(fn,sn);
This is the basic standard specification, fn and sn are bound or unbound variables of any type.
name(in fn, out sn)=getName(fn,sn);
This restricts the standard specification, because fn must be bound and sn must be unbound when this predicate is called, otherwise it will be ignored. You could overload is by following it with the first example above.
name(String fn, out sn)=getName(fn,sn);
Now fn must be a String object, but may be bound or unbound, sn must still be unbound.

Points of note:
  • Unless your variable name is one char long, it should start with a small letter or it will be mistaken for a type binding
  • in and out should not be used as variable names
  • Predicates can be overloaded, but they are overloaded in order (same as Prolog), meaning that if you have a predicate which has no binding or type restrictions, it should be the final specified predicate
  • No error will be thrown if your bindings cause a predicate call that you did not expect

Monday, 28 May 2007

Modifications of standard Prolog

Deepweaver changes a number of standard Prolog syntactical features to bring it closer to Java, and make pattern cuts more familiar to Java developers

Declaring a predicate is no longer done using the Prolog iff term :-, instead the = symbol is used.
Terminating a predicate is no longer performed using the fullstop symbol . instead the semicolon is used ; Since the semicolon in Prolog represents or, this has now been replaced with the pipe character, |
Comments are now of standard Java form, so instead of % we have // for single line comments and /* .. */ for multiline comments
Negation is slightly different from standard Prolog in that \+ is no longer used to reperesent negation, instead use the not(A) predicate.

Finally, its worth noting that in a .dw file, only predicates preceeded by a question mark will be executed. One should declare all the required predicates and then select the one to be executed by writing ?runMe(A,B); at the end of the file.

eg. well_located(A,B) = statement(A,X), not(between(s, X, B, true));