The main distinction between LogicAJ and AspectJ is LogicAJ's concept of logic meta-variables:

A logic meta-variable (LMV) is a metavariable that matches one base language element (e.g. a field access). Syntactically, it is an identifier with a prepended question mark: LMV ::=?Identifier

A logic list meta-variable (LLMV) is a metavariable that matches a list of base langauge elements (e.g. a parameter list). Syntactically, it is an identifier with two prepended question marks: LLMV ::=??Identifier

Meta-variables are like named wildcards. Unlike with wildcards, one can refer to the value matched by a meta-variable by using the same meta-variable in another expression within the same scope. All occurrences of the same meta-variable in a scope must match the same value.

If a meta-variable occurs only once in a scope it can be replaced by the “anonymous” metavariable, whose name is the underscore: ”?_”. Every occurrence of the anonymous meta-variable is considered to be a different meta-variable (matches of the anonymous metavariable do not
need to agree on the matched value). The underscore can also be used as an anonymous list meta-variable, ”??_”.

Anonymous meta-variables are the equivlent of simple wildcards. ”?_” is equivalent to ”*” and ”??_” is equivalent to ”..”.
Although meta-variables subsume wildcards, the AspectJ-like wildcard syntax is supported in LogicAJ for backward compatibility and for the convenience of former AspectJ programmers.

Checking the type of meta-variables is done at weave-time, not at compile-time of individual aspects. So you will get weaving errors if e.g. a variable of type identifier is used in an arithmetic expression. However, you will never get run-time exceptions because of wrong types, as would be the case if you used reflection.
Compile-time checking of meta-variable types will be part of a future release.

You may use fully qualified names, identifiers or strings where a value of type type is expected and vice versa. The value will be automatically converted, e.g.:

type(?stringType) &&
equals(?stringType, java.lang.String)

is equivalent to

equals(?stringType, "java.lang.String")

Also an automatic conversion is attempted for string values used in arithmetic expressions.
Of course, this will result in a weaving error if the value can not be converted.

Meta-variables and list meta-variables can be used in advice, introductions and the patterns of pointcuts. In patterns, they can be used (at least) wherever wildcards (*, **, or ..) can be used in AspectJ:

Below, the type of an argument is postfixed to the argument name separated by a colon.
If the type is omitted arbitrary meta-variable types can be used.
See also the the Valid Bindings paragraph above.

Selective Pointcuts With Metavariables

General Syntax

Examples

call(MethodPat|ConstructorPat)

call ( void Foo.m(int) ) a call to the method void Foo.m(int) call ( Foo.new(..) ) a call to any constructor of Foo

execution(MethodPat|ConstructorPat)

execution ( * Foo.*(..) throws IOException ) the execution of any method of Foo that is declared to throw IOException execution ( !public Foo .new(..) ) the execution of any non-public constructor of Foo

withincode(MethodPat|ConstructorPat)

withincode ( void Figure.move() ) any join point where the associated code is defined in the method void Figure.move()

get(FieldPat)

get ( int Point.x ) when int Point.x is read

set(FieldPat)

set ( !private * Point.* ) when any field of Point is assigned

within(TypePat)

within( com.bigboxco.* ) any join point where the associated code is defined in the package com.bigboxco

target(TypePat | Var)

target( java.io.InputPort ) any join point where the target (receiver) object is an instance of java.io.InputPort The target pointcut can also be used to bind advice parameters: after(Object o) : call(..) && target(o) {...}

this(TypePat | Var)

this( Point )any join point where the currently executing object is an instance of Point

args(ArgsPat)

args( java.io.InputPort, int )any join point where there are two arguments, the first an instance of java.io.InputPort, and the second an int args( *, int ) any join point where there are two arguments, the second of which is an int. args( short, .., short ) any join point with at least two arguments, the first and last of which are shorts

selects matching methods and binds meta-variables in the pattern; the optional LMV binds the body of the method, e.g:method ( void Foo.?m(int) ) selects all method in the type Foo with return type void and int parameter; all method names are bound to ?m

field(FieldPat)

selects matching fields and binds meta-variables in the pattern; the optional LMV binds the initializer of the field

directsubtype(Subtype:type, Supertype:type)

binds Subtype to direct subtype of the second argument Supertype

subtype(Subtype:type, Supertype:type)

binds Subtype to all subtypes (interfaces or classes) of the second argument Supertype

Removes ??RemoveElements from ??FromList and binds the resulting list to ??ResultList.

Types

concreteAspect(?Type:type)

Bind ?Type to the enclosing concrete aspect's class.

pattern( Arg, RegEx:string [, groupX:string] )

Checks if the pattern RegEx matches the first argument.

E.g. pattern("bbacc","(.*)a(.*)",?Match1, "cc") where ?Match1 matches the first group ("aa").

Be aware: Shorthand characters like \w do not work. Use [a-z] etc. instead.

For details on the RegEx flavour see also the last paragraph of the SWI-Prolog RegEx documentation.

types(??Elements:list, ??Types:list)

Unifies ??Types with the list of types of ??Elements, where Elements may contain parameter declarations or argument expressions

package(?Package:string)

Unifies ?Package with the packages defined in the project

sourcetype(PType:type)

Checks if Type is available in source code. Otherwise it was read from a library (as byte code). This is important since LogicAJ only weaves aspects into source classes.

typename(?Type:type,?SimpleTypeName:string)

binds the type name of ?Type to ?SimpleTypeName

typepackage(?Type:type,?PackageName:string)

binds the package name of ?Type to ?PackageName

packagetolist(?Package:string,??PackageNames:list)

e.g. packagetolist("org.cs3", ["org","cs3"])

arrayType(?ComponentType:type, ?Arity:int, ?Type:type)

e.g. arrayType("java.lang.Object[]",1, "java.lang.Object[]")

aspect(?Type:type)

check if ?Type is an aspect class

type(?Type:type)

selects matching types and binds meta-variables in the pattern, e.g.:
type(?type) or
type(?packagename.?name)
binds ?package to the complete package name of the package of all types and ?name to the name of the type
notice:in future ?packagename will only bind package name parts without dots, e.g. pack1;lists of (sub-)package names may be bound with ??package,e.g. type(??prefix.?api.internal.??rest.?classname)

class(?Class:type)

like type(..), but ensures that TypePat is a class

interface(?Interface:type)

Checks if ?Interface is an interface.

enum(?Enumeration:type)

Checks if ?Enumeration is an enumeraration.

annotationType(?Annotation:type)

Checks if ?Annotation is an annotation type.

Arithmetic

lt(Number1:int,Number2:int)

True if Number1 is smaller than Number2

le(Number1:int,Number2:int)

True if Number1 is smaller or equal to Number2

gt(Number1:int, Number2:int)

True if Number1 is greater than Number2

ge(Number1:int, Number2:int)

True if Number1 is greater or equal to Number2

ge(Number1:int, Number2:int,Sum:int)

True if Sum=Number1+Number2. At least two of the three arguments must be instantiated to integers.