How you can Fix Vista Registry Glitches – Three or more Simple Actions is All You'll need
Please try the following routine to see if you can get Malwarebytes to run.
Click on Start, click Run, and then type devmgmt.msc and click OK
On the View menu click on Show hidden devices
Browse to Non-Plug and Play Drivers and you should see something like TDSSserv.sys
Highlight that driver and right click on it and select DISABLE
Now RESTART your computer.
Download a copy of Malwarebytes but DO NOT run it yet.
Rename the downloaded installer file to any generic name such as your own name but keep the .EXE extension on the file and run it.
Once the program is installed go to the UPDATE tab and try to update the program if you can.
Then go to the SCANNER tab and run a Quick Scan and allow MBAM to fix anything found.
Data types
The ATL data type scheme is very close, but not similar, to the one defined by OCL. The following schema provides an overview of the data type's structure considered in ATL. The different data types presented in this schema represent the possible instances of the OclType class.
The root element of the OclType instances structure is the abstract OclAny type, from which all other considered types directly or indirectly inherit. ATL considers six main kinds of data types: the primitive data types, the collection data types, the tuple type, the map type, the enumeration type and the model element type. Note that the map data type is implemented by ATL as an additional facility, but does not appear in the OCL specification.
The class OclType can be considered as the definition of a type in the scope of the ATL language. The different elements appearing in the schema represent the type instances that are defined by OCL (except the map and the ATL module data types), and implemented within the ATL engine.
The OCL primitive data types correspond to the basic data types of the language (the string, boolean and numerical types). The set of collection types introduced by OCL provides ATL developers with different semantics for the handling of collections of elements. Additional data types include the enumerations, a tuple and a mapping data type and the model element data type. This last corresponds to the type of the entities that may be declared within the models handled by the ATL engine. Finally, the ATL module data type, which is specific to the ATL language, is associated with the running ATL units (either modules or queries).
Before going further in the description of these data types, it must be noted that each OCL expression, including the operations associated with each kind of data type (that are presented along with their respective data type), is defined in the context of an instance of a specific type. In ATL as in OCL, the reserved keyword self is used to refer to this contextual instance.
OclType operations
The class OclType corresponds to the definition of the type instances specified by OCL. It is associated with a specific OCL operation: allInstances(). This operation, which accepts no parameter, returns a set containing all the currently existing instances of the type self.
The ATL implementation provides an additional operation that enables to get all the instances of a given type that belong to a given metamodel. Thus, the allInstancesFrom(metamodel : String) operation returns a set containing the instances of type self that are defined within the model namely identified by metamodel.
OclAny operations
This section describes a set of operations that are common to all existing data types. The syntax used to call an operation from a variable in ATL follows the classical dot notation:
self.operation_name(parameters)
ATL currently provides support for the following OCL-defined operations:
- comparison operators: =, <>;
- oclIsUndefined() returns a boolean value stating whether self is undefined;
- oclIsKindOf(t : oclType) returns a boolean value stating whether self is an either an instance of t or of one of its subtypes;
- oclIsTypeOf(t : oclType) returns a boolean value stating whether self is an instance of t.
The operations oclIsNew() and oclAsType() defined by OCL are currently not supported by the ATL engine. ATL however implements a number of additional operations:
- toString() returns a string representation of self. Note that the operation may return irrelevant string values for a few remaining types;
- oclType() returns the oclType of self;
- asSequence(), asSet(), asBag() respectively return a sequence, a set or a bag containing self. These operations are redefined for the collection types;
- output(s : String) writes the string s to the Eclipse console. Since the operation has no return value, it shall only be used in ATL imperative blocks;
- debug(s : String) returns the self value and writes the “s : self_value” string to the eclipse console;
- refSetValue(name : String, val : oclAny) is a reflective operation that enables to set the self feature identified by name to value val. It returns self;
- refGetValue(name : String) is a reflective operation that returns the value of the self feature identified by name;
- refImmediateComposite() is a reflective operation that returns the immediate composite (e.g. the immediate container) of self;
- refInvokeOperation(opName : String, args : Sequence) is a reflective operation that enables to invoke the self operation named opName with the sequence of parameter contained by args.
The ATL Module data type
The ATL Module data type is specific to the ATL language. This internal data type aims to represent the ATL unit (either a module or a query) that is currently run by the ATL engine. There exists a single instance of this data type, and developers can refer to it (in their ATL code) using the variable thisModule. The thisModule variable makes it possible to access the helpers and the attributes that have been declared in the context of the ATL module.
The ATL Module data type also provides the resolveTemp operation. This specific operation makes it possible to point, from an ATL rule, to any of the target model elements (including non-default ones) that will be generated from a given source model element by an ATL matched rule.
The operation resolveTemp has the following declaration:
resolveTemp(var, target_pattern_name)
The parameter var corresponds to an ATL variable that contains the source model element from which the searched target model element is produced. The parameter target_pattern_name is a string value that encodes the name of the target pattern element that maps the provided source model element (contained by var) into the searched target model element.
Note that, as it is defined in the scope of the ATL module, this operation must be called from the variable thisModule. The resolveTemp operation must not be called before the completion of the matching phase. This means that the operation can be called from:
- the target pattern and do sections of any matched rule;
- the target pattern and do sections of a called rule, provided that this called rule is executed after the matching phase (e.g. is not called from a transformation entrypoint).
ATL developers may note that the operation call does not specify the matched rule from which the generated target model element comes from. However, as explained in the Rules section, a source model element should not be matched by more than one matched rule. As a consequence, the concerned matched rule can be derived from the specified source model element.
Here is an example of resolveTemp use:
rule AtoAnnotedB {
from
a : MMA!A
to
ann : MMB!Annotation (),
b : MMB!B (
annotation <- ann
)
}
In this first rule, an object of type A is transformed into two objects: a B (the b variable) instance annoted with an Annotation instance (the ann variable).
In the second rule, we want to refer to the newly created B elements from their A source. We assume that
- the ARef type has a reference named ref pointing to an A element
- the BRef type has a reference named ref pointing to an B element
rule ARefToBRef {
from
aRef : MMA!ARef
to
bRef : MMB!BRef (
ref <- thisModule.resolveTemp(aRef.ref, 'b')
)
}
Notice that the variable name is passed as a String to the resolveTemp method.
Primitive data types
OCL defines four basic primitive data types:
- the Boolean data type, for which possible values are true or false;
- the Integer data type which is associated with the integer numerical values (1, -5, 2, 34, 26524, …);
- the Real data type which is associated with the floating numerical values (1.5, 3.14, …);
- the String data type ('To be or not to be', …). A string is defined between '. The escape character '\' enables to include ' characters within handled string variables. Note that, in OCL:
- a character is encoded as a one-character string;
- the characters composing a string are numbered from 1 to the size of the string.
According to the considered data type (string, numerical values and boolean values), OCL defines a number of specific operations. They are detailed in the following sections along with some additional functions provided by the ATL engine.
Boolean data type operations
The set of OCL operations defined for the boolean data type is the following:
- logical operators: and, or, xor, not;
- implies(b : Boolean) returns false if self is true and b is false, and
returns true otherwise.
Boolean expressions evaluation
In this case:
if (exp1 and exp2)
then …
else …
endif
exp2 will always be evaluated, regardless of the result of the first expression. ATL evaluates it like this:
if (exp1.and(exp2))
then …
else …
endif
So remember that in this case:
if (self.attributes->size() > 0
and self.attributes->first().attr)
Even though the first member is false, there may be a call of the “attr” property on an undefined element, which will cause an error.
String data type operations
OCL defines the following operations for the string data type:
- size() returns the number of characters contained by the string self;
- concat(s : String) returns a string in which the specified string s is concatenated to the end of self;
- substring(lower : Integer, upper : Integer) returns the substring of self starting from character lower to character upper;
- toInteger() and toReal().
Besides the OCL-defined operations, ATL implements a number of additional operations for the string data type:
- comparison operators: <, >, =>, =<;
- the string concatenation operator (+) can be used as a shortcut for the string concat() function;
- toUpper(), toLower() respectively return an upper/lower case copy of self;
- toSequence() returns the sequence of characters (e.g. of one-character strings) corresponding to self;
- trim() returns a copy of self with leading and trailing white spaces (' ', '\t', '\n', '\f', '\r') omitted;
- startsWith(s : String), endsWith(s : String) return a boolean value respectively stating whether self starts/ends with s;
- indexOf(s : String), lastIndexOf(s : String) respectively return the index (an integer value) within self of the first/last occurrence of the specified substring s;
- split(regex : String) splits the self string around matches of the regular expression regex. Specification of regular expression must follow the definition of Java regular expressions. Result is returned as a sequence of strings;
- replaceAll(c1 : String, c2 : String) returns a copy of self in which each occurrence of character c1 is replaced with the character c2. Note that both c1 and c2 are specified as OCL strings. However the function only considers the first character of each of the provided strings;
- regexReplaceAll(regex : String, replacement : String) returns a copy of self in which each substring of this string that matches the given regular expression regex is replaced with the given replacement. Specification of regular expression must follow the definition of Java regular expressions.
As a last point, ATL currently defines two additional functions that make it possible to write strings to outputs. These functions are useful for redirecting the result of ATL queries, but they may also be used for debugging purposes:
- writeTo(fileName : String) enables to write the self string into the file identified by the string fileName. Note that this string may encode either a full or a relative path to the file. In the last case, the path is relative to the \eclipse directory from which the ATL tool kit is run. If the identified file already exists, the function writes the new content over this existing file;
- println() writes the self string onto the default output, that is the Eclipse console.
Note that these two functions are provided as temporary solutions as the ATL toolkit does still not provide any integrated solution for the redirection of the result of ATL queries. They are likely to be removed from future releases of the ATL tool suite.
Numerical data type operations
The following OCL operations are defined for both OCL numerical data types (integer and real):
- comparison operators: <, >, =>, =<;
- binary operators: *, +, -, /, max(), min();
- unary operator: abs().
Note that the – unary operator defined by OCL (that returns the negative value of self) is not implemented in current version of ATL. As a consequence, a -x negative numerical value has to be declared as the result of a call to the – binary operator: 0-x.
OCL also defines some operations that are specific to the integer and the real data types:
- integer operation: div(), mod();
- real operations: floor(), round().
Besides the OCL-defined operations, ATL provides a set of additional functions. The toString() operation, available for both the integer and real data types returns a string representing the integer/real value of self. There also exist a set of ATL operations specific to the real data type:
- cos(), sin(), tan(), acos(), asin();
- toDegrees(), toRadians();
- exp(), log(), sqrt().
Examples
In the following, some usage examples of OCL operations on primitive data types are illustrated:
- testing whether a string is of type OclAny:
'test'.oclIsTypeOf(OclAny)- evaluates to
false
- evaluates to
- testing whether a string is of kind OclAny:
'test'.oclIsKindOf(OclAny)- evaluates to
true
- evaluates to
- boolean operations:
trueorfalse- evaluates to
true
- evaluates to
- computing a substring of a given string:
'test'.substring(2, 3)- evaluates to 'es'
- casting a string into upper case:
'test'.toUpper()- evaluates to 'TEST'
- casting a string into a sequence:
'test'.toSequence()- evaluates to
Sequence{'t', 'e', 's', 't'}
- evaluates to
- checking whether a string ends by a given substring:
'test'.endsWith('ast')- evaluates to
false
- evaluates to
- getting last index of character “t” in string “test”:
'test'.lastIndexOf('t')- evaluates to 4
- replacing character “t” by character “o” in string “test”:
'test'.replaceAll('t', 'o')- evaluates to 'oeso'
- replacing occurrences of regular expression “a*” by string “A” in string “aaabaftaap”:
'aaabaftaap'.regexReplaceAll('a*', 'A')- evaluates to 'AbAftAp'
- integer division:
23 div 2 or 23."div"(2)- evaluates to 11
- real division:
23/2- evaluates to 11.5
Collection data types
OCL defines a number of collection data types that provide developers with different ways to handle collections of elements. The provided collection types are Set, OrderedSet, Bag and Sequence. Collection is the common abstract superclass of these different types of collections.
The existing collection classes have the following characteristics:
- Set is a collection without duplicates. Set has no order;
- OrderedSet is a collection without duplicates. OrderedSet is ordered;
- Bag is a collection in which duplicates are allowed. Bag has no order;
- Sequence is a collection in which duplicates are allowed. Sequence is ordered.
A collection can be seen as a template data type. This means that the declaration of a collection data type has to include the type of the elements that will be contained by the type instances. Whatever the type of the contained elements, the declaration of a collection data type has to conform to the following scheme:
collection_type(element_datatype)
The supported collection data types are Set, OrderedSet, Sequence and Bag. The element data type can be any supported oclType, including another collection type.
The definition of a collection variable is achieved as follows:
collection_type{elements}
Please note that the brackets used in the type definition must here be replaced by curly brackets. Examples of collection type definitions and instantiations can be found here.
Operations on collections
ATL provides a large number of operations in the context of the different supported collection types. Note that there exists a specific syntax for invoking an operation onto a collection type:
self->operation_name(parameters)
The different kinds of existing OCL collections share a number of common operations:
- size() returns the number of elements in the collection self;
- includes(o : oclAny) returns a boolean stating whether the object o is part of the collection self;
- excludes(o : oclAny) returns a boolean stating whether the object o is not part of the collection self;
- count(o : oclAny) returns the number of times the object o occurs in the collection self;
- includesAll(c : Collection) returns a boolean stating whether all the objects contained by the collection c are part of the self collection;
- excludesAll(c : Collection) returns a boolean stating whether none of the objects contained by the collection c are part of the self collection;
- isEmpty() returns a boolean stating whether the collection self is empty;
- notEmpty() returns a boolean stating whether the collection self is not empty;
- sum() returns a value that corresponds to the addition of all elements in self. These elements must be of a type that support the + operation.
Note that the product() operation defined by OCL is unsupported by the current ATL implementation. However, ATL defines three additional operations in the context of a collection (OCL defines similar operations in the context of each collection type):
- asBag() returns a bag containing the elements of the self collection. Order is lost from a sequence or an ordered set. Has no effect in the context of a bag;
- asSequence() returns a sequence containing the elements of the self collection. Introduces an order from a bag or a set. Has no effect in the context of a sequence;
- asSet() returns a set containing the elements of the self collection. Order is lost from a sequence or an ordered set. Duplicates are removed from a bag or a sequence. Has no effect in the context of a set.
Note that, in the current ATL version, the casting operation asOrderedSet() defined by OCL is implemented for none of the collection types.
Sequence data type operations
The sequence type supports all the collection operations. OCL defines a number of additional operations that are specific to sequences:
- union(c : Collection) returns a sequence composed of all elements of self followed by the elements of c;
- flatten() returns a sequence directly containing the children of the nested subordinate collections contained by self;
- append(o : oclAny) returns a copy of self with the element o added at the end of the sequence;
- prepend(o : oclAny) returns a copy of self with the element o added at the beginning of the sequence;
- insertAt(n : Integer, o : oclAny), returns a copy of self with the element o added at rank n of the sequence;
- subSequence(lower : Integer, upper : Integer) returns a subsequence of self starting from rank lower to rank upper (both bounds being included);
- at(n : Integer) returns the element located at rank n in self;
- indexOf(o : oclAny) returns the rank of first occurrence of o in self;
- first() returns the first element of self (oclUndefined if self is empty);
- last() returns the last element of self (oclUndefined if self is empty);
- including(o : oclAny) returns a copy of self with the element o added at the end of the sequence;
- excluding(o : oclAny) returns a copy of self with all occurrences of element o removed.
Set data type operations
Set supports all collection operations and some specific ones:
- union(c : Collection) returns a set composed of the elements of self and the elements of c with duplicates removed (they may appear within c, and between c and self elements);
- intersection(c : Collection) returns a set composed of the elements that appear both in self and c;
- operator – (s : Set) returns a set composed of the elements of self that are not in s;
- including(o : oclAny), returns a copy of self with the element o if not already present in self;
- excluding(o : oclAny), returns a copy of self with the element o removed from the set;
- symetricDifference(s : Set) returns a set composed of the elements that are in self or s, but not in both.
Note that the flatten() operation defined by OCL is not implemented in the current version of ATL.
OrderedSet data type operations
The sequence type supports all the collection operations. OCL defines a number of additional operations that are specific to ordered sets:
- append(o : oclAny) returns a copy of self with the element o added at the end of the ordered set if it does not already appear in self;
- prepend(o : oclAny) returns a copy of self with the element o added at the beginning of the ordered set if it does not already appear in self;
- insertAt(n : Integer, o : oclAny), returns a copy of self with the element o added at rank n of the ordered set if it does not already appear in self;
- subOrderedSet (lower : Integer, upper : Integer) returns a subsequence of self starting from rank lower to rank upper (both bounds being included);
- at(n : Integer) returns the element located at rank n in self;
- indexOf(o : oclAny) returns the rank of first occurrence of o in self;
- first() returns the first element of self (oclUndefined if self is empty);
- last() returns the last element of self (oclUndefined if self is empty).
Besides this set of operations specified by OCL, ATL implements the following additional functions:
- union(c : Collection) returns an ordered set composed of the elements of self followed by the elements of c with duplicates removed (they may appear within c, and between c and self elements);
- flatten() returns an ordered set directly containing the children of the nested subordinate collections contained by self;
- including(o : oclAny) returns a copy of self with the element o added at the end of the ordered set if it does not already appear in self;
- excluding(o : oclAny) returns a copy of self with the o removed.
Bag data type operations
- including(o : oclAny) returns a copy of self with the element o added at the end of the ordered set if it does not already appear in self;
- excluding(o : oclAny) returns a copy of self with the o removed.
- flatten() returns a sequence directly containing the children of the nested subordinate collections contained by self;
Iterating over collections
The OCL specification defines a number of iterative operations, also called iterative expressions, on the collection types. The main difference between a classical operation and an iterative expression on a collection is that the iterator accepts an expression as parameter, whereas operations only deal with data. The definition of an iterative expression includes:
- the iterated collection, which is referred as the source collection;
- the iterator variables declared in iterative expressions, which are referred as the iterators;
- the expression passed as parameter to the operation, which is referred as the iterator body.
The syntax used to call an iterative expression is the following:
source->operation_name(iterators | body)
ATL currently provides support for the following set of defined iterative expressions:
- exists(body) returns a boolean value stating whether body evaluates to true for at least one element of the source collection;
- forAll(body) returns a boolean value stating whether body evaluates to true for all elements of the source collection;
- isUnique(body) returns a boolean value stating whether body evaluates to a different value for each element of the source collection;
- any(body) returns one element of the source collection for which body evaluates to true. If body never evaluates to true, the operation returns OclUndefined;
- one(body) returns a boolean value stating whether there is exactly one element of the source collection for which body evaluates to true;
- collect(body) returns a collection of elements which results in applying body to each element of the source collection;
- select(body) returns the subset of the source collection for which body evaluates to true;
- reject(body) returns the subset of the source collection for which body evaluates to false (is equivalent to select(not body));
- sortedBy(body) returns a collection ordered according to body from the lowest to the highest value. Elements of the source collection must have the < operator defined.
Note that the collect() operation provided by ATL implements the semantics of the collectNested() operation defined in the OCL specification. Getting the semantics of the collect() operation as defined by OCL can simply be achieved with ATL by calling the flatten() operation onto the result provided by the ATL collect() iterative expression, as follows:
source->collect(iterator | body)->flatten()
The ATL language introduces another constraint compared to the OCL specification. The specification indeed allows declaring multiple iterators in the scope of the exists() and the forAll() iterative expressions. This feature is not supported by the current ATL implementation, in which the number of iterator is limited to one, whatever the considered iterative expression.
Besides these predefined iterative operations, OCL specifies a more generic collection iterator, named iterate(). This iterative expression has an iterator, an accumulator and a body. The accumulator corresponds to an initialized variable declaration. The body of an iterate() expression is an expression that should make use of both the declared iterator and accumulator. The value returned by an iterate() expression corresponds to the value of the accumulator variable once the last iteration has been performed.
An iterative expression is defined with the following syntax:
source->iterate(iterator, variable_declaration = init_exp |
body
)
Examples
In the following, some operations on collections are illustrated:
- declaring the sequence of integer type:
Sequence(Integer) - specifying a sequence of integers:
Sequence{1, 2, 3} - declaring the set of sequences of string type:
Set(Sequence(String)) - specifying a set of sequences of strings:
Set{Sequence{'monday'}, Sequence{'march', 'april', 'may'}} - testing whether a bag is empty:
Bag{1, 2, 3}->isEmpty()- evaluates to
false
- evaluates to
- testing whether a set contains an element: Set{1, 2, 3}->includes(1)
- evaluates to
true
- evaluates to
- testing whether a set contains all the elements of another set: Set{1, 2, 3}->includesAll(Set{3, 2})
- evaluates to
true
- evaluates to
- getting the size of a sequence:
Sequence{1, 2, 3}->size()- evaluates to 3
- note that
Set{3, 3, 3}->size()evaluates to 1 since the set data type eliminates duplicates
- getting the first element of an ordered set sequence:
OrderedSet{1, 2, 3}->first()- evaluates to 1
- computing the union of two sequences:
Sequence{1, 2, 3}->union(Sequence{7, 3, 5})- evaluates to
Sequence{1, 2, 3, 7, 3, 5}
- evaluates to
- computing the union of two sets:
Set{1, 2, 3}->union(Set{7, 3, 5})- evaluates to
Set{1, 2, 3, 7}
- evaluates to
- flattening a sequence of sequences:
Sequence{Sequence{1, 2}, Sequence{3, 5, 2}, Sequence{1}}->flatten()- evaluates to
Sequence{1, 2, 3, 5, 2, 1}
- evaluates to
- computing a subsequence of a sequence:
Sequence{Sequence{1, 2}, Sequence{3, 5, 2}, Sequence{1}}->subSequence(2, 3)- evaluates to
Sequence{ Sequence{3, 5, 2}, Sequence{1}}
- evaluates to
- inserting an element at a given position into a sequence:
Sequence{5, 15, 20}->insertAt(2, 10)- evaluates to
Sequence{5, 10, 15, 20}
- evaluates to
- computing the intersection of two sets:
Set{1, 2, 3}->intersection(Set{7, 3, 5})- evaluates to
Set{3}
- evaluates to
- computing the symmetric difference of two sets:
Set{1, 2, 3}->symetricDifference(Set{7, 3, 5})- evaluates to
Set{1, 2, 7, 5}
- evaluates to
- selecting all elements of a sequence that are smaller or equal to 3:
Sequence{1, 2, 3, 4, 5, 6}->select(i | i <= 3)- evaluates to
Set{1, 2, 3}
- evaluates to
- collecting the names of all MOF classes:
MOF!Class.allInstances()->collect(e | e.name)- checking whether all the numbers in a sequence are greater than 2:
Sequence{12, 13, 12}->forAll(i | i > 2) - evalutes to
true
- checking whether all the numbers in a sequence are greater than 2:
- checking whether there is only one element of the sequence that is greater that 2:
Sequence{12, 13, 12}->one(i | i > 2)- evalutes to
false
- evalutes to
- checking whether there exists a number in the sequence that is greater than 2:
Sequence{12, 13, 12}->exists(i | i > 2)- evaluates to
true
- evaluates to
- computing the sum of the positive integer of a sequence using the iterate instruction:
Sequence{8, -1, 2, 2, -3}->iterate(e; res : Integer = 0 |
if e > 0
then res + e
else res
endif
)- evaluates to 12;
- is equivalent to
Sequence{8, -1, 2, 2, -3}->select(e | e > 0)->sum()
Enumeration data types
An enumeration is an OclType. It has a name just as any other data type. However, compared to the data presented up to now, the enumerations have to be defined within the source and target metamodels of a transformation.
With the OCL specification, referring to an enumeration literal (e.g. an enumeration defined value) is achieved by specifying the enumeration type (e.g. the name of the enumeration), followed by two double-points and the enumeration value. Consider, as an example, an enumeration named Gender that defines two possible values, male and female. Accessing to the female value of this enumeration type in OCL is achieved as follows: Gender::female.
The current ATL implementation differs from the OCL specification. Access to enumeration values is simply achieved by prefixing the enumeration by a sharp character (the enumeration type is no more required): #female.
The enumeration data type is associated with no specific operation.
Tuple data type
The tuple data type enables to compose several values into a single variable. A tuple consists into a number of named parts that may each have a distinct type. Note that a tuple type is not named. As a consequence, a declared tuple type has to be identified by its full declaration each time it is required.
Each part of a tuple type is associated with an OclType and is identified by a unique name. The declaration of a tuple data type must conform to the following syntax:
TupleType(var_name1 : var_type1, …, var_nameN : var_typeN)
Note that the order in which the different parts are declared is not significant. As an example, it is possible to consider the declaration of a tuple type associating an Author model element from the MMAuthor metamodel with a couple of strings encoding the title of a book and the name of the editor of this book:
TupleType(a : MMAuthor!Author, title : String, editor : String)
The instantiation of a declared tuple variable has to respect the following syntax:
Tuple{var_name1 [: var_type1]? = init_exp1, …, var_namen [: var_typen]? = init_expn}
When declaring a tuple instance, the types of the tuple parts can be omitted. As a consequence, the two following tuple instantiations corresponding to the tuple type defined above are equivalent:
Tuple{editor : String = 'ATL Eds.', title : String = 'ATL Manual', a : MMAuthor!Author = anAuthor}
Tuple{title = 'ATL Manual', a = anAuthor, editor = 'ATL Eds.'}
As for the declaration of a tuple type, the instantiation of the different parts of a tuple variable may be performed in any order.
The different parts of a tuple structure can be accessed using the same dot notation that is used for the invocation of operations or the access to model element attributes. Thus, the expression
Tuple{title = 'ATL Manual', a = anAuthor, editor = 'ATL Eds.'}.title
provides access to the title part of the tuple.
Besides the set of common operations, the current ATL implementation defines an additional casting operation in the context of the tuple dada type: the asMap() operation returns a map variable in which the name of the tuple parts are associated with their respective values.
Map data type
Provided as an additional facility in the ATL implementation, the map data type does not belong to the OCL specification. This data type enables to manage a structure in which each value is associated with a unique key that enables to access it (see the Java Map interface for further details).
The declaration of a map type has to conform to the following syntax:
Map(key_type, value_type)
Note that, as a tuple type, a map type is not named, which again implies to specify the full type declaration when required. The following map declaration associates some Author model element values with integer keys:
Map(Integer, MMAuthor!Author)
Instantiating a map variable is achieved according to the following syntax:
Map{(key1, value1), …, (keyn, valuen)}
As an example, the following expression instantiates a two entries map corresponding to the map type declared above:
Map{(0, anAuthor1), (1, anAuthor2)}
Besides the set of common operations, the ATL implementation provides the following operations on map data:
- get(key : oclAny) returns the value associated with key within the self map (or OclUndefined if key is not a key of self);
- including(key : oclAny, val : oclAny) returns a copy of self in which the couple (key, val) has been inserted if key is not already a key of self;
- union(m : Map) returns a map containing all self elements to which are added those elements of m whose key does not appear in self;
- getKeys() returns a set containing all the keys of self;
- getValues() returns a bag containing all the values of self.
Model element data type
The last kind of data type introduced by the OCL specification corresponds to the model elements. These last are defined within the source and target metamodels of an ATL transformation. Metamodels usually define a number of different model elements (also called classes).
In ATL, model element variables are referred to by means of the notation metamodel!class in which metamodel identifies (through its name) one of the metamodels handled by the transformation, and class points to a given model element (e.g. class) of this metamodel. Note that, as opposed to the OCL notation, which does not specify the metamodel a given class comes from, the ATL notation makes it possible to handle several metamodel at once.
A model element has a number of features that can be either attributes or references. Both are accessed through the dot notation self.feature. Thus, in the context of the MMAuthor metamodel, the expression anAuthor.name enables to access to the attribute name of the instance anAuthor of the Author class.
In ATL, the model elements can only be generated by means of the ATL rules (either matched or called rules). Initializing a newly generated model element consists in initializing its different features. Such assignments are operated by means of the bindings of the rules target pattern elements.
Please note that the operation oclIsUndefined(), defined for the OclAny data type, tests whether the value of an expression is undefined. This operation is useful when applied on an attribute with a multiplicity zero to one (which is void or not). However, attributes with the multiplicity n are usually represented as collections that may be empty and not void.
Full name reference to metamodel classes
It is also possible to include the full path using the following scheme:
<Package1Name>::<Package2Name>::<ClassifierName>
Actually the ATL Parser doesn't deal well with “::” so we need to surround the path using “.
For instance, using the metamodel excerpt given above, we could write:
MM!”P1::C1″
MM!”P1::P2::C2″
MM!”P3::C3″
In some cases, full name reference is required to avoid ambiguity due to name collision.
Let us consider the following metamodel:
package P1 {
class C1 {}
package P2 {
class C1 {}
}
}
package P3 {
class C1 {}
}
Using MM!C1 is incorrect because it cannot reliably me mapped to a specific class.
If you try to do this, a warning will be reported in the ATL console.
In this case, it is mandatory to write:
MM!”P1::C1″
MM!”P1::P2::C1″
MM!”P3::C1″
Examples
Here is a sample of OCL expressions using features of model elements. They are defined in the context of the MOF metamodel:
- collect the names of all MOF classes:
MOF!Class.allInstances()->collect(e | e.name)
- getting the names of all primitive MOF types by filtering:
MOF!DataType.allInstances()
->select(e | e.oclIsTypeOf(MOF!PrimitiveType))
->collect(e| e.name)
- getting the names of all primitive MOF types the simple way:
MOF!PrimitiveType.allInstances()->collect(e| e.name)
- an enumeration instance in MOF:
MOF!VisibilityKind.labels
- getting the names of all classes inheriting from more than one class:
MOF!Class.allInstances()
->select(e | e.supertypes->size() > 1)
->collect(e | e.name)
ATL Comments
In ATL, as in the OCL standard, comments start with two consecutive hyphens “–” and end at the end of the line.
The ATL editor in Eclipse colours comments with dark green, if the standard configuration is used:
– this is an example of a comment
OCL Declarative Expressions
Besides the declarative expressions that correspond to the instances of the supported data types, as well as the invocation of operations on these data types, OCL defines additional declarative expressions that aim to enable developers to structure OCL code. This section is dedicated to the description of these declarative expressions.
There exist two kinds of advanced declarative expressions: the “if” and the “let” expressions. The “if” expression provides an alternative expression facility. The “let” expression, as for it, enables to define and initialize new OCL variables.
If expression
An OCL “if” expression is expressed with an if-then-else-endif structure. As an expression, an “if” expression should be evaluated (e.g. must have a value) in any cases. This means that the “else” clause of an “if” expression can not be omitted. All “if” expressions must conform to the following syntax:
if condition
then
exp1
else
exp2
endif
The condition of the “if” expression is a boolean expression. According to the evaluation of this boolean expression, the “if” expression will return the value corresponding to either exp1 (in case condition is evaluated to true) or exp2 (in case condition is evaluated to false). This is illustrated by the following simple “if” expression:
if 3 > 2
then
'three is greater than two'
else
'this case should never occur'
endif
Note that the different parts of an “if” expression can, in turn, include another composed OCL expression, including operation invocations, “let” expressions or nested “if” expressions. As an example, it is possible to consider the following example:
if mySequence->notEmpty()
then
if mySequence->includes(myElement)
then
'the element is at position '
+ mySequence->indexOf(myElement).toString()
else
'the sequence does not contain the element'
endif
else
'the sequence is empty'
endif
Let expression
The OCL “let” expression enables the definition of variables. A “let” expression has to conform to the following syntax:
let var_name : var_type = var_init_exp in exp
The identifier var_name corresponds to the name of the declared variable. var_type identifies the type of the declared variable. A variable declared by means of a “let” expression must be initialized with the var_init_exp. The initialization expression can be of any available OCL expression type, including nested “let” expressions. Finally, the in keyword introduces the expression in which the newly declared variable can be used. Again, this expression can be of any existing OCL expression type. This is illustrated by the following simple example:
let a : Integer = 1 in a + 1
Several “let” expressions can be enchained in order to declare several variables, as in the following example:
let x : Real =
if aNumber > 0
then
aNumber.sqrt()
else
aNumber.square()
endif
in let y : Real = 2 in x/y
An OCL variable is visible from is declaration to the end of the OCL expression it belongs to. Note that, although it is not advised, OCL allows developers to declare several variables of the same name within a single expression. In such a case, the lastly declared variable will hide the other variables having the same name.
The “let” expressions also prove to be very useful at the debugging stage. Indeed, the ATL development tools integrate debugging facilities that enable, among other things, to consult the value of the declared variables during the execution of an ATL program. In many cases, it proves to be useful to also be able to consult the value returned by a complex OCL expression. This could be achieved with few modification of the OCL code by declaring an OCL variable initialized with the complex expression to be checked. By this means, the value computed by the expression will be stored in an OCL variable, and thus be available for visualization during the debugging of the ATL program.
In order to illustrate this point, consider the following expression:
aSequence->first().square()
It is here assumed that the collection aSequence is a sequence of Real elements. In case this sequence is empty, the invocation of the operation first() will return the value OclUndefined. Invoked onto OclUndefined, the operation square() will raise an error at runtime. In such a case, it may be interesting to be able to check, at debug stage, whether the first element exists or is undefined by storing its value in a dedicated variable. This is the purpose of the following expression:
let firstElt : Real = aSequence->first() in firstElt.square()
Other expressions
Besides the “if” and “let” structural expressions, the OCL language enables to define different kinds of expressions whose syntax has been introduced in the Data Types section. These expressions include:
- the constant expressions, which correspond to a constant value of any supported data type;
- the helper/attribute call expressions which correspond to the call of an helper/attribute either defined in the context of the ATL module or of any source model element. The expression is resolved into the value returned by the helper/attribute;
- the operation call expressions, which correspond to the call of a standard operation defined for a supported data type. The expression is resolved into the value returned by the operation;
- the collection iterative expressions, which correspond to the call of an iterative expression on a supported collection data type. The expression is resolved into the value returned by the called iterative operation.
Expressions tips & tricks
A number of errors, while designing OCL expressions in ATL, come from the evaluation mode of these OCL expressions. Indeed, in many languages, such as C++ and Java, there exists an optimiser that stops the evaluation of logical expressions when finding either a true value followed by the “or” logical operator or a false value followed by the “and” logical operator. No matter the rest of the expression may result into an error or an exception, the expression will be successfully evaluated.
As opposed to these common programming languages, the semantics of composed expressions, as defined by OCL, are such that each expression has to be fully evaluated. As a consequence, some expressions that usually appear to be correct will raise errors in ATL, as illustrated by the following example:
not person.oclIsUndefined() and person.name = 'Isabel'
This expression will therefore raise an error for an undefined person model element when evaluating the expression person.name. An error-free way to express an equivalent logical expression is:
if person.oclIsUndefined()
then
false
else
person.name = 'Isabel'
endif
The same remark can be applied similarly to the logical expressions that use the logical “or” operator, such as:
person.oclIsUndefined() or person.name = 'Isabel'
The correct way to express this logical expression is:
if person.oclIsUndefined()
then
true
else
person.name = 'Isabel'
endif
Note that the logical expressions that are likely to raise this kind of errors may be embedded in more complex OCL expressions:
collection->select(person | not person.oclIsUndefined() and person.name = 'Isabel')
Using the same rewriting rule, this expression can be transformed into the correct following expression:
collection->select(person |
if person.oclIsUndefined()
then
false
else
person.name = 'Isabel'
endif
)
There may exist several ways to rewrite an incorrect expression. Thus, the following expression will compute the same result:
collection
->select(person | not person.oclIsUndefined())
->select(person | person.name = 'Isabel')
Note that the first solution should here be preferred to this one for efficient reasons: the first solution iterates the collection only once.
ATL Helpers
ATL enables developers to define methods within the different kinds of ATL units. In the ATL context, these methods are called helpers. They make it possible to define factorized ATL code that can then be called from different points of an ATL program.
There exist two different, although very similar from their syntax, kinds of helpers: the functional and the attribute helpers. Both kinds of helpers must be defined in the context of a given data type. However, compared to an attribute helper, which is commonly referred to as an attribute, a functional helper, referred to as a helper, can accept parameters. This difference implies some differences in the execution semantics of both helper kinds.
Helpers
ATL helpers can be viewed as the ATL equivalent to methods. They make it possible to define factorized ATL code that can be called from different points of an ATL transformation.
An ATL helper is defined according to the following scheme:
helper [context context_type]? def : helper_name(parameters) : return_type = exp;
Each helper is characterized by its context (context_type), its name (helper_name), its set of parameters (parameters) and its return type (return_type). The context of a helper is introduced by the keyword context. It defines the kind of elements the helper applies to, that is, the type of the elements from which it will be possible to invoke it. Note that the context may be omitted in a helper definition. In such a case, the helper is associated with the global context of the ATL module. This means that, in the scope of such a helper, the variable self refers to the run module/query itself.
The name of a helper is introduced by the keyword def. As its context, it is part of the signature of the helper (along with the parameters and the return_type). A helper accepts a set of parameters that is specified between brackets after the helper's name. A parameter definition includes both the parameter name and the parameter type, as specified by the following scheme:
parameter_name : parameter_type
Several parameters can be declared by separating them with a comma (“,”). The name of the parameter (parameter_name) is a variable identifier within the helper. This means that, within a given helper definition, each parameter name must be unique. Note that the specified context type as well as the parameters' type and the return type may be of any of the data types supported by ATL.
The body of a helper is specified as an OCL expression. This expression can be of any of the supported expression types. As an example, it is possible to consider the following helper:
helper def : averageLowerThan(s : Sequence(Integer), value : Real) : Boolean =
let avg : Real = s->sum()/s->size() in avg < value;
This helper, named averageLowerThan, is defined in the context of the ATL module (since no context is explicitly specified). It aims to compute a boolean value stating whether the average of the values contained by an integer sequence (the s parameter) is strictly lower than a given real value (the value parameter). The body of the helper consists in a “let” expression which defines and initializes the avg variable. This variable is then compared to the reference value.
Note that several helpers may have the same name in a single transformation. However, helpers with a same name must have distinct signatures to be distinguishable by the ATL engine (see Limitations).
Calling super helpers
The super keyword lets you call helpers with the same name defined on a super type of the current type.
Suppose you have the following metamodel:
class A {}
class B extends A {}
Then you can write:
helper context A def: test() : Integer = 1;
helper context B def: test() : Integer = super.test() + 1;
Attributes
Besides helpers, the ATL language makes it possible to define attributes. Compared to a helper, an attribute can be viewed as a constant that is specified within a specific context. The major difference between a helper and an attribute definition is that the attribute accepts no parameter.
The syntax used to define an ATL attribute is very close to the definition of functional helpers. The only difference is that the attribute syntax does not enable to define any parameter:
helper [context context_type]? def : attribute_name : return_type = exp;
As for a helper, the context definition can be omitted in the declaration of an attribute. In this case, the attribute will be associated with the ATL module context. The following attribute, which is related to the MMPerson metamodel, can be considered as an example:
helper def : getYoungest : MMPerson!Person =
let allPersons : Sequence(MMPerson!Person) =
MMPerson!Person.allInstances()->asSequence() in
allPersons->iterate(p; y : MMPerson!Person = allPersons->first() |
if p.age < y.age
then
p
else
y
endif
);
This attribute, named getYoungest, is defined within the ATL module context. It applies to a source metamodel MMPerson that contains Person model elements. It aims to compute the youngest person of the source model (the return type is therefore MMPerson!Person). The attribute body consists in a “let” expression that defines the allPersons variable. This variable is a sequence of MMPerson!Person model elements that contains all the persons defined within the source model (note that the computed set has to be cast into a sequence).
The computed sequence is then iterated by means of an iterate expression in which the iteration variable p represents the currently iterated person. The iterate expression results into a MMPerson!Person model element which will correspond to the youngest of the iterated persons. This result is contained by the variable y which is initialized to the first person of the allPersons sequence (in order to get this first person, it is required to define a sequence rather than a set). The body of this iterate expression consists in an “if” expression that simply compares the ages of the current youngest person to the one of the currently iterated person. According to the result of this comparison, the “if” expression will either return the previous youngest person or the iterated one.
Declaring a parameter-less helper and an attribute may appear to be equivalent. However, there exists a major difference between the helpers and the attributes execution semantics. The code of a helper is executed each time this helper is invoked. As opposed to a helper, an attribute accepts no parameter. This means that, for a given execution context (an input model element or the ATL module), an attribute will always return the same value. The ATL engine therefore computes the return value of an attribute only once, either when this attribute is invoked for the first time, or at the transformation/query initialization stage for those attributes that are declared in the context of the ATL module.
Limitations
Current implementation suffers from three limitations in the domain of helpers/attributes. The first one deals with the definition of the signature of the helpers. Helpers are indeed identified through their signature which includes the helper name, its context and its parameters. However, current implementation only considers the subset composed of the helper name and the helper context of this signature: the helpers' parameters do not make it possible to discriminate helpers that have a same name and same context. This implies that all the helpers defined within a given context in an ATL program must have a distinct name. This restriction also concerns the helpers that are defined within a library which is imported in either a query or a module.
The second limitation concerns the definition of helpers in the context of a collection type. Such definitions are actually unsupported by the ATL engine. A simple solution to get round this problem is to move the collection element from context to parameters and to declare the helper in the context of the ATL module. Consider the definition of a helper that aims to select among a set of Person model elements those who are younger than a given age. This helper should be defined as:
helper context Set(MMPerson!Person) def : getYoungPersons(age : Integer) :
Set(MMPerson!Person) =
self->select(p | p.age < age);
Taking into account the current ATL limitation, this helper can be defined as follows:
helper def : getYoungPersons(s : Set(MMPerson!Person), age : Integer) :
Set(MMPerson!Person) =
s->select(p | p.age < age);
Note that this change has a very limited impact onto the body of the helper. The only difference is the self variable used in the previous version of the helper that has to be replaced by the name of the parameter that represents the collection (s).
Finally, last limitation concerning helpers is related to the library unit. Current implementation does not support the definition of attributes within an ATL library. The developer should therefore substitute a parameter-less helper to each of the attributes of the developed libraries. As an example, in the scope of a library, the following attribute:
helper context String def : getFirstChar : String = self.substring(1, 1);
must be replaced by its corresponding helper:
helper context String def : getFirstChar() : String = self.substring(1, 1);
ATL Rules
In the scope of the ATL language, the generation of target model elements is achieved through the specification of transformation rules. ATL defines two different kinds of transformation rules: the matched and the called rules. A matched rule enables to match some of the model elements of a source model, and to generate from them a number of distinct target model elements.
As opposed to matched rules, a called rule has to be invoked from an ATL imperative block in order to be executed. ATL imperative code can be defined within either the action block of matched rules, or the body of the called rules
ATL imperative code
ATL enables developers to specify imperative code within dedicated blocks, either in matched or called rules. An imperative block is composed of sequence of imperative statements. As in the Java C or C++ languages, each statement must be ended with a semicolon character (“;”).
The current ATL implementation provides three kinds of statements: the assignment statements, the “if” statements and the “for” statements. Note that, as opposed to the OCL expressions, these statements do not return any value. As a consequence, they can not be used in the scope of some ATL declarative code. The three different imperative statements are detailed in the following subsections.
The assignment statement
The ATL assignment statement enables to assign values to either attributes that are defined in the context of the ATL module, or to target model element features. The syntax of the assignment statement conforms to the following scheme:
target <- exp;
As specified, the target of the assignment is either a module attribute or an output model element feature. The assigned expression (exp) can be of any of the supported ATL expressions.
Consider, as a first example, the following attribute definition which defines an integer counter in the context of the ATL module:
helper def: counter : Integer = 0;
The value of this counter attribute can be incremented in the scope of an imperative block using an assignment operation:
thisModule.counter <- thisModule.counter + 1;
The assignment statement can be used in the same way to assign values to model element features in the way. For instance, considering a Person model element aPerson, it is possible to write:
aPerson.father.age <- aPerson.age + 25;
It is possible to initialize the references of a newly generated target model element. The following assignment illustrates this with the assignment of another locally generated (e.g. in the same rule) model element (anotherPerson):
aPerson.father <- anotherPerson;
In the same way, it is also possible to assign to a reference a model element that is generated by a different matched rule. As described here, in such a case, the assigned element is the corresponding source element. If this last does not correspond to a rule default target pattern element, it is required to use the operation resolveTemp(). Note however that the operation resolveTemp shall be called only once the matching phase of the transformation has completed. This means that resolveTemp cannot be invoked neither from the entrypoint called rule, nor from another called rule invoked from this entrypoint.
The if statement
The “if” statement enables to define alternative imperative treatments. “if” statements have to conform to the following syntax:
if(condition) {
statements1
}
[else {
statements2
}]?
Each “if” statement defines a condition. This condition must be an OCL expression that returns a boolean value. An “if” statement must also include a “then” statements section. This section, specified between curved brackets, contains the sequence of statements (statements1) that is executed when the conditional expression is evaluated to true. An “if” statement may also include an optional “else” statements section. When specified, this section has to follow the “then” statements section. It is introduced by the keyword else, and must also be defined between curved brackets. This section contains the optional sequence of statements (statements2) that has to be executed when the conditional expression is evaluated to false.
The following example illustrates the use of an “if” statement limited to a simple “then” section:
if(aPerson.gender = #male) {
thisModule.menNb <- thisModule.menNb + 1;
thisModule.men->including(aPerson);
}
Next example presents an “if” expression defining both a “then” and an “else” sections, with a nested “if” statement:
if(aPerson.gender = #male) {
thisModule.fullName <- 'Mr. ' + aPerson.name + ' ' + aPerson.surname;
}
else {
if(aPerson.isSingle) {
thisModule.fullName <- 'Miss ' + aPerson.name;
thisModule.surname <- aPerson.surname;
}
else {
thisModule.fullName <- 'Mrs. ' + aPerson.name;
thisModule.surname <- aPerson.marriedTo.surname;
}
thisModule.fullName <- thisModule.fullName + ' ' + thisModule.surname;
}
Note that the curved brackets delimitating both the “then” and the “else” sections may be omitted when the corresponding sections contain a single statement, as in the following example:
if(aPerson.gender = #male)
thisModule.men->including(aPerson);
else
thisModule.women->including(aPerson);
The for statement
The “for” statement enables to define iterative imperative computations. A “for” statement has to conform to the following syntax:
for(iterator in collection) {
statements
}
The “for” statement defines an iteration variable (iterator) that will iterate over the different elements of the reference collection. For each of these elements, the sequence of statements contained by the “for” statement will be executed.
The following example, also related to the MMPerson metamodel illustrates the use of the “for” imperative statement:
for(p in MMPerson!Person.allInstances()) {
if(p.gender = #male)
thisModule.men->including(aPerson);
else
thisModule.women->including(aPerson);
}
Current limitations
It is currently not possible to declare variables within ATL imperative blocks. The variables that can be used in the scope of these blocks are:
- The source and target model elements declared in the local matched rule;
- The target model elements declared in the local called matched rule;
- The variables locally declared (e.g. within the rule);
- The attributes declared in the context of the ATL module.
Note that the current implantation does not enable to modify the locally defined variables from an imperative assignment statement. This means that, beside the source and target model elements, the only variables that can be modified from an imperative block are the attributes that have been defined in the context of the ATL module. As a consequence, the modifiable variables that may be required in the scope of an imperative bock must, with the current implementation, be declared as ATL module attributes.
Matched Rules
The ATL matched rule mechanism provides ATL developers with a convenient mean to specify the way target model elements must be generated from source model elements. For this purpose, a matched rule enables to specify 1) which source model element must be matched, 2) the number and the type of the generated target model elements, and 3) the way these target model elements must be initialized from the matched source elements. The specification of a matched rule has to conform to the following syntax:
rule rule_name {
from
in_var : in_type [(
condition
)]?
[using {
var1 : var_type1 = init_exp1;
...
varn : var_typen = init_expn;
}]?
to
out_var1 : out_type1 (
bindings1
),
out_var2 : distinct out_type2 foreach(e in collection)(
bindings2
),
…
out_varn : out_typen (
bindingsn
)
[do {
statements
}]?
}
Each matched rule is identified by its name (rule_name). A matched rule name must be unique within an ATL transformation. An ATL matched rule is composed of two mandatory (the from and the to parts) and two optional (the using and the do parts) sections. Note that the different variables that may be declared in the scope of a rule (the source and target pattern elements and the local variables) must have a unique name. This restriction does not apply to the OCL expressions contained by this rule. The different sections of an ATL matched rule are detailed in the following subsections.
Source pattern
The from section corresponds to the rule source pattern. This pattern, composed of a single source pattern element contains the source variable declaration (in_var). This declaration specifies the type of the source model elements that will be matched by the rule (in_type). It can moreover contain, between brackets, an optional boolean expression (condition) that enable to target a subset of the transformation source model elements that conform to the source type. If the source pattern element includes no explicit condition, all the source model elements of the transformation that conform to the specified source type will be matched by the rule.
The following code excerpt illustrates the syntax of the from section:
from
p : MMPerson!Person (
p.name = 'Smith'
)
Note that the following excerpt
from
p : MMPerson!Person (
true
)
is equivalent to:
from
p : MMPerson!Person
Local variables section
The optional using section makes it possible to locally declare a number of local variables. The variables declared in this section can be used in the using section itself (provided that the variable is not invoked before its declaration), as well as in the to and the do sections. Each declared variable is identified by its name (vari) and its type (var_typei), and must be initialized using an OCL expression.
The following code excerpt illustrates the use of the using section:
from
c : GeometricElement!Circle
using {
pi : Real = 3.14;
area : Real = pi * c.radius.square();
}
Simple target pattern element
The to section corresponds to the target pattern of the rule. It contains a number of target pattern elements. This section is mandatory and must contain at least one target pattern element. When several target pattern elements are specified, they must be separated by comas (“,”). Note that the first target pattern element corresponds to the default pattern element of the rule. This means that the target model element associated with this rule's default target pattern can be viewed as the default counterpart of the source model element matched by the rule.
In ATL, there exist two different kinds of target pattern elements: the simple and the iterative ones. Each target pattern element, whatever its type, corresponds to a variable declaration characterized by a name (out_vari) and a type (out_typei). A simple target pattern is specified as a set of bindings that define the way the features (either attributes or references) of the generated element must be initialized. Each binding has to conform to the following syntax:
feature_name <- exp
The name of the initialized feature (feature_name) has to refer to a feature of the variable associated with the target pattern element, as defined in its metamodel. The specified expression (exp) is an OCL expression. When a target pattern element contains more than one binding, the successive bindings have to be separated by comas. Note that it is not required to explicitly initialize all the features of a generated model element. The default value of the features that are not initialized by means of an explicit binding may change according to the model handler used to access the model element. As a consequence, ATL developers are strongly encouraged not to produce code that depends on these default values.
As an example, it is possible to consider the following ATL rule, which is defined in the context of the Biblio metamodel defined on the
Biblio metamodel:
rule Journal2Book {
from
j : Biblio!Journal
to
b : Biblio!Book (
title <- j.title + '_(' + j.vol + '):' + j.num,
authors <- j.articles
->collect(e | e.authors)->flatten()->asSet()
chapters <- j.articles,
pagesNb <- j.articles->collect(e | e.pagesNb)->sum()
)
}
This rule aims to produce a Book model element from a Journal model element. It initializes the title, authors, chapters and pagesNb features of the generated Book:
- the title of the Book corresponds to the title of the journal concatenated with its volume (vol) and its number (num);
- the chapters of the Book correspond to the model elements that will be generated for the articles of the source Journal;
- the authors of the Book correspond to the authors of the different articles of the source Journal, without any duplicate;
- the attribute pagesNb is initialized with the sum of the number of pages (pagesNb) of the articles of the source Journal.
This example has illustrated the initialization of the attributes of a generated target model element. As previously stated, the bindings also enable to initialize reference features. Three main cases therefore have to be considered:
- assigning to a reference a target model element generated by the current rule;
- assigning to a reference the default target model element of another rule;
- assigning to a reference a non-default target model element of another rule.
The first case (assigning a model element produced by the same rule) is also the simplest one: the considered reference can be initialized with the name of the other target pattern element. Consider the following example in which the rule Case1 has two target pattern model elements (o_1 and o_2), with o_1 having a reference to a Class2 model element defined (linkToClass2):
rule Case1 {
from
i : MM_A!ClassA
to
o_1 : MM_B!Class1 (
linkToClass2 <- o_2
),
o_2 : MM_B!Class2 (
…
)
}
The reference feature is here simply initialized with the local target pattern element that corresponds to the target model element.
In the second case (assigning the default target element of another rule), the considered reference has to be initialized with the source model element which is matched by the remote rule for generating the target model element to be assigned. In the following example, the rule Case2_R1 aims to generate a target model element (o_1) that has a reference to a target model element that corresponds to the default target pattern (o_1) of the rule Case2_R2. Assuming that the source model element matched by Case2_R1 has a reference (linkToClassB) to the relevant MM_A!ClassB source model element, this assignment is expressed as follows:
rule Case2_R1 {
from
i : MM_A!ClassA
to
o_1 : MM_B!Class1 (
linkToClass2 <- i.linkToClassB
)
}
rule Case2_R2 {
from
i : MM_A!ClassB
to
o_1 : MM_B!Class2 (
…
),
…
}
The reference is here initialized with the source model element that is matched by rule Case2_R2 when generating the target model element MM_B!Class2.
It may also happen that a developer wants to initialize a reference with a non-default target pattern element of a remote rule. This last case requires the use of the resolveTemp() operation defined in the context of the ATL module. This operation makes it possible to access the target model elements that are associated with the non-default target pattern elements of a remote rule. It accepts two parameters: the source model element which is matched by the remote rule for generating the target model element to be assigned, and the name of the target pattern element it is associated with. This is illustrated with the following example, which is similar to the previous one, except that the target model element to be assigned is not generated by the default target pattern of rule Case3_R2.
rule Case3_R1 {
from
i : MM_A!ClassA
to
o_1 : MM_B!Class1 (
linkToClass2 <- thisModule.resolveTemp(i.linkToClassB, 'o_n')
)
}
rule Case3_R2 {
from
in : MM_A!ClassB
to
o_1 : MM_B!Class3 (
…
),
…
o_n : MM_B!Class2 (
…
),
…
}
Compared to the previous case, the reference is here initialized by invoking the operation resolveTemp() with the source model element (i.linkToClassB, the same that in the previous example) and the name of the target pattern (“o_n“) as arguments.
Iterative target pattern element
As opposed to the simple target pattern element, which allows generating a single target model element, the iterative target pattern element makes it possible to generate a set of target model elements conforming to a same type. An iterative target pattern element is introduced by the keyword distinct. It produces a target model element for each element belonging to a given reference ordered collection (either a Sequence or an OrderedSet). This collection, along with its associated iterator (e), is introduced by the keyword foreach. As for a simple target pattern element, an iterative target pattern element defines a number of bindings. These bindings specify the way the features of the target model elements generated by this target pattern element will be initialized.
The following example aims to generate a number of distinct Cell model elements equal to the size of a collection:
using {
coll : Sequence(String) = Sequence{'a', 'b', 'c'};
}
to
cells : distinct Table!Cell foreach(e in coll)(
content <- e,
id <- coll->indexOf(e)
)
Note that the collection operation indexOf can be used here to compute a unique column id because the reference collection (coll) does not contain multiple instances of a same element in the collection. Otherwise, the id of the multiple instances of a same element would all have been initialized with the index of the first instance of this element.
Since the reference collection is defined, in this example, as a constant, both its size and its content are known. It is thus possible, instead of using a single iterative target pattern element, to define as many simple target pattern elements as the number of elements in the collection. However, the use of an iterative out pattern element will be required when working with a collection which is a priori unknown (for instance, a collection that comes from a source model).
Attention must be paid when assigning a collection to a target model element feature in the scope of an iterative target pattern element. Indeed, when executing an iterative target pattern element, the ATL engine iterates over the reference collection, but also, in the same time, over the collection expressions that are assigned to features within this pattern element. During the iteration over the reference collection, the current element of a collection expression is assigned to its targeted feature. This has two main consequences:
- the assigned collections must have the same size that the reference collection of the target pattern element;
- assigning a collection to a feature in the scope of an iterative target pattern element requires to build a collection of collections.
The following example illustrates the way to assign a collection to feature in the scope of an iterative out pattern element:
using {
coll : Sequence(String) = Sequence{'a', 'b', 'c'};
}
to
lines : distinct Table!Line foreach(e in coll)(
id <- coll->indexOf(e),
cell_titles <-
Sequence{
Set{'PlayerA_Score1', 'PlayerB_Score1'},
Set{'PlayerA_Score2', 'PlayerB_Score2'},
Set{'PlayerA_Total', 'PlayerB_ Total', 'Total'}
}
)
This example is quite similar to the previous one. Instead of generating some Cell model elements, it generates a Line model element for each element of a reference collection (coll). Each line is associated with a unique id, which is computed in the same way it was in the previous example. The difference is here that each line is also characterized by a sequence of strings that encode the title of the different cells of the line.
In order to associate each generated Line model element with its own set of cell titles, the property cell_titles is initialized with a sequence containing as many elements as the reference collection. Each generated line will be associated with its corresponding element in this sequence (the one positioned at the same rank). Thus, the first generated line will be associated with the “PlayerA_Score1″ and “PlayerB_Score1″ cell titles whereas the third line will be associated with the “PlayerA_Total”, “PlayerB_Total” and “Total” cell titles. Please note that:
- the type of the assigned collections (here a set) can differ from the type of the collection in which assigned collections are grouped (here a sequence):
- the type of the grouping collection must conform to the type of the reference collection when the defined order has to be respected;
- the type of the assigned collection have to conform to the semantics of the model element being initialized;
- the assigned collections are not supposed to have the same size.
Attention must also be paid when referring to the elements generated in the scope of an iterative target pattern. Thus, in the scope of a simple target pattern element, an iterative target pattern variable refers to the whole set of generated elements that are generated by the corresponding pattern element. It is also possible to invoke an iterative target pattern variable from another iterative target pattern element provided that: 1) both iterative target pattern elements belong to the same rule, and 2) both iterative target pattern elements iterate over the same ordered collection. In such a case, the variable refers to the target model element generated by the current iteration.
The following code excerpt illustrates the different ways to refer to elements produced by iterative target pattern elements:
using {
coll : Sequence(String) = Sequence{'Score1', 'Score2', 'Total'};
}
to
tab : Table!Table (
lines <- t_lines
),
t_lines : distinct Table!Line foreach(e in coll)(
id <- coll->indexOf(e),
caption <- line_captions
),
line_captions : distinct Table!Caption foreach(e in coll)(
content <- e
)
This new example is inspired from the previous ones. The objective is here to create a Table model element, itself composed of Line model elements. Each Line has to be associated with its own Caption model element. In the scope of the simple target pattern element tab, the variable t_lines refers to the whole sequence of generated Line model elements.
Since both iterative target pattern elements iterate over the same reference collection, the variable line_captions used in the t_lines target pattern element refers to a single of the Caption model elements generated by the line_captions target pattern element. Since the used reference collection is ordered, the line_captions variable will refer to the Caption generated from the same element of the reference collection.
Imperative block section
The last section of an ATL matched rule is the optional do section. This section enables to specify a sequence of ATL imperative statements that will be executed once the initialization of the target model elements generated by the rule has completed. This imperative block can in particular be used to initialize some model element features that have not been initialized using the declarative bindings, or to modify some already initialized features.
The imperative block provides a convenient way to simply assign a unique id to each of the generated model elements. The following example, related to the
Biblio metamodel, illustrates this point:
helper def : id : Integer = 0;
…
rule Journal2Book {
from
j : Biblio!Journal
to
b : Biblio!Book (
…
)
do {
thisModule.id <- thisModule.id + 1;
b.id <- thisModule.id;
}
}
In this example, a global id variable is defined in the context of the ATL module, and initialized to zero. In order to associate each generated model element with a unique id, the imperative block of the matched rule simply increments the value of the id global variable and assigned this new value to the id property of the generated model element.
Lazy Rules
How to call lazy rules:
Let a simple lazy rule:
lazy rule getCross {
from
i: ecore!EObject
to
rel: metamodel!Relationship (
)
}
We can call it from a matched rule as follows:
rule Example {
from
s : ecore!EObject
to
t : metamodel!Node (
name <- s.toString(),
edges <- thisModule.getCross(s)
)
}
If we want to call lazy rule multiple times:
rule Example {
from
s : ecore!EObject
to
t : metamodel!Node (
name <- s.toString(),
edges <- ecore!EClass.allInstancesFrom('yourmodel')->collect(e | thisModule.getCross(e))
)
}
Unique Lazy Rules
Declaring a lazy rule as unique, with the following syntax:
unique lazy rule Example{
…
}
give it the following behavior:
When a unique lazy rule is executed, it always returns the same target element for a given source element. The target element is retrieved by navigating the internal traceability links, in a way similar to standard rules.
Non-unique lazy rule do not navigate the traceability links, and create new target elements at each execution.
Called Rules
Besides matched rules, ATL defines an additional kind of rules enabling to explicitly generate target model elements from imperative code. Except for the entrypoint called rule, this kind of rules must be explicitly called from an ATL imperative block. The specification of a called rule has to conform to the following syntax:
? rule rule_name(parameters){
[using {
var1 : var_type1 = init_exp1;
...
varn : var_typen = init_expn;
}]?
[to
out_var1 : out_type1 (
bindings1
),
out_var2 : distinct out_type2 foreach(e in collection)(
bindings2
),
...
out_varn : out_typen (
bindingsn
)]?
[do {
statements
}]?
}
A called rule is identified by its name (rule_name). A called rule name has to be unique within an ATL transformation, and must not collide with a helper name. Moreover, a called rule cannot be called “main”. A called rule can optionally be declared as the transformation entrypoint. An ATL transformation can include one entrypoint called rule. Compared to the other called rules, the entrypoint called rule does not need to be explicitly called: it is implicitly invoked at the beginning of the transformation execution, once the module initialization phase has completed.
A called rule can accept parameters. They have to be specified in the same way they are for helpers. It is composed of three optional sections: the using, the to and the do sections. Compared to a matched rule, a called rule has no from section, and its to section is optional. Note however that the semantics of the available sections are similar to those defined for matched rules:
- the using section makes it possible to declare and initialize local variables. A declared variable is visible from the remaining of the using section as well as from the to and the do ones;
- the to section corresponds to the target pattern of the called rule. It contains a number of target pattern elements (either simple or iterative target pattern elements). As opposed to a matched rule, there is here no source matched model element whose features may be used in order to initialize the features of the target model elements;
- the do section enables to specify an imperative instruction block. If a to section is specified, the imperative block is executed once the computation of the target pattern has completed.
The following code excerpt, provides a called rule example:
helper def: metamodel : KM3!Metamodel = OclUndefined;
…
entrypoint rule Metamodel() {
to
t : KM3!Metamodel
do {
thisModule.metamodel <- t;
}
}
This called rule is defined as the transformation entry point. This means that it is executed between the initialization and the matching phases. It generates a Metamodel model element. The code specified within the imperative block makes a variable (metamodel) defined in the context of the ATL module pointing to this model element. By this mean, the generated Metamodel remains accessible for further computation during the transformation.
Rule inheritance
There is two keywords introduced by rules inheritance: abstract and extends. They can be used like this:
abstract rule A {
from
using
to
do
}
rule B extends A {
from
using
to
do
}
rule C extends B {
from
using
to
do
}
When ATL compiles this transformation, it is the same as if you gave this as input:
rule B {
from
using
to [toA.bindings union toB.bindings]
do
}
rule C {
from
using
to [toA.bindings union toB.bindings union toC.bindings]
do
}
However, there are some limitations and constraints. First, the compiler does not support multiple inheritances and it is not planned to be implemented. Constraints are the following:
- sub rules (e.g. B or C) input pattern (i.e. the from part) has to match a subset of its super rule. For instance, if you match particular class in a super rule, you have to have a more restrictive filter or match a sub class.
- input pattern variables names have to be the same in super and sub rules.
- output pattern variables names have to be the same in super and sub rules for output pattern you want the union.
Here is a complete example to illustrate. It is a KM3-copier, i.e. every model element from the source model is copied as-is to the target model:
module Copy;
create OUT : MM from IN : MM;
rule CopyDataType extends CopyClassifier {
from
s : MM!DataType
to
t : MM!DataType
}
rule CopyEnumeration extends CopyClassifier {
from
s : MM!Enumeration
to
t : MM!Enumeration (
literals <- s.literals
)
}
rule CopyParameter extends CopyTypedElement {
from
s : MM!Parameter
to
t : MM!Parameter
}
rule CopyReference extends CopyStructuralFeature {
from
s : MM!Reference
to
t : MM!Reference (
isContainer <- s.isContainer,
opposite <- s.opposite
)
}
rule CopyTypedElement extends CopyModelElement {
from
s : MM!TypedElement
to
t : MM!TypedElement (
lower <- s.lower,
upper <- s.upper,
isOrdered <- s.isOrdered,
isUnique <- s.isUnique,
type <- s.type
)
}
rule CopyOperation extends CopyTypedElement {
from
s : MM!Operation
to
t : MM!Operation (
parameters <- s.parameters
)
}
rule CopyAttribute extends CopyStructuralFeature {
from
s : MM!Attribute
to
t : MM!Attribute
}
rule CopyEnumLiteral extends CopyModelElement {
from
s : MM!EnumLiteral
to
t : MM!EnumLiteral
}
rule CopyPackage extends CopyModelElement {
from
s : MM!Package
to
t : MM!Package (
contents <- s.contents
)
}
rule CopyClass extends CopyClassifier {
from
s : MM!Class
to
t : MM!Class (
isAbstract <- s.isAbstract,
supertypes <- s.supertypes,
structuralFeatures <- s.structuralFeatures,
operations <- s.operations
)
}
rule CopyClassifier extends CopyModelElement {
from
s : MM!Classifier
to
t : MM!Classifier
}
abstract rule CopyModelElement extends CopyLocatedElement {
from
s : MM!ModelElement
to
t : MM!ModelElement (
name <- s.name
)
}
rule CopyMetamodel extends CopyLocatedElement {
from
s : MM!Metamodel
to
t : MM!Metamodel (
contents <- s.contents
)
}
abstract rule CopyLocatedElement {
from
s : MM!LocatedElement
to
t : MM!LocatedElement (
location <- s.location
)
}
rule CopyStructuralFeature extends CopyTypedElement {
from
s : MM!StructuralFeature
to
t : MM!StructuralFeature (
subsetOf <- s.subsetOf,
derivedFrom <- s.derivedFrom
)
}
Rules usage
Here are three types of declarative rules:
- Matched rules are applied once for each match. A given set of elements may only be matched by one standard rule,
- Lazy rules are applied as many times for each match as it is referred to from other rules (possibly never for some matches).
- Unique lazy rules are applied at most once for each match, and only if it is referred to from other rules.
The following table summarizes their differences with respect to the number of time they are applied.
Do not, at any point, endeavor to thoroughly clean or delete data in your registry manually if you are not an expert, or can adhere to a step-by-step manual provided by authorities on the way to sparkling why does my computer run slow. You may conclude up causing more injury than excellent for your PC.
Learn a Step-by-step Tactic to Restore and Clean the home windows
I wrote an article that talked about installing Linux on your Windows machine and not voiding the warranty as Windows will still be running on the machine. Though, I might have made a mistake in the first part. You may want to go to http://wubi-installer.org to actually install Ubuntu Linux using Windows. Select every option you want, enter the user name and password that you want, unblock anything that Windows says is blocked because of virus blocking software or firewalls as long as you know that these files are related to downloading Ubuntu Linux.
My last article only went through setting up the printer on Gutenprint.
I have now found I like the set up of Xubuntu. Each distribution of Linux is a little different in the desktop environment, but they all basically run the same way. The slight difference may be a few commands that can be used at the terminal or the “Konsole.”
I cannot guarantee that all of these commands will work for your computer as all computers are a little bit different, but most likely, they will work.
The first thing that you need to do after setting up and choosing the installation of Linux that you'd like is to find the Applications menu. While Ubuntu comes packaged with Open Office, Xubuntu does not. Instead, it comes packaged with Abi Word. So, you will need to download Open Office as well as a few other programs. You can install them all at once which will take a long time or you can install them one by one. Each program will take a shorter time and as long as you do not mind what you are doing being interrupted when it is time to continue installing a program, you can play games or type or be on the Internet.
Of course, you need to make sure that your Internet is connected. Make sure that the wire or the wireless is turned on so the computer can detect the network. You then need to click on the different little icons until you find the one that will show you the networks being detected. Select your own network and follow the set up screen. If you have one of those encryption codes, you will need to be able to type it into the box so it can set up your Internet.
Once you have the Internet detected and running, you can continue the set up process.
Now you need to find the menu spot that says “Applications.” After this, click on it and go to “Add/Remove.” A window will appear. It will do a quick check and then next to the word “show” there is a drop down box. You want it to say “All available applications.”
You need to type in key words to find all of the programs that you need.
First, type in “Open Office.” It will find a lot of things. If it doesn't already have a check mark, select “OpenOffice.org Word Processor.” A dialog box will come up asking if you want to install the rest of the items. Agree to that and then you can continue finding the other things.
Type in “VLC.” Make sure there is a check in the box next to “VLC Media Player.” (VLC is a media player that will play DVDs and CDs.)
Type in “Pidgin” and make sure there is a check in the box next to “Pidgin Internet Messenger.”
(Pidgin will handle AIM, Yahoo! IM, ICQ, and other messaging devices all in one neat package.)
Type in “Gwibber.” Again, make sure there is a check next to “Gwibber Microblogging Client.”
(Gwibber Microblogging Client is a Twitter client that also had some other microblogging clients built in to the program.)
Type in “Audacity.” Make sure there is a check in the box next to “Audacity.”
(Audacity is a sound recording and sound manipulation program.)
Type in “Klam” and make sure the box next to “KlamAV” is checked.
(KlamAV is AntiVirus Software.)
Once all of this is done either as one whole step, or each thing separately, push the button that says “Apply Changes.”
Wait for the changes to apply.
If you want to, you can restart your computer, but a nice part of Linux is that it is rare that you actually have to restart the computer.
Now it is time to check if everything is working. If you can hear sounds, and that is all you need, you are good to go.
You can try going to YouTube and playing videos. If you have a built in microphone, you can open Audacity by going to the Applications menu and down to “Multimedia” and then to “Audacity.” Open it and hit the red circle button to try to record. Talk for a little while or sing a song. Then hit the square button. Hopefully it detected sound and the line is not flat.
The line may look flat, but if you heard sounds earlier, it may have recorded your voice and your microphone may not have good pick up. In Audacity, go to the Edit menu. Go down until you find “Select.” At the menu that pops out of the side, select “All.” After that, go to the menu that says “Effect.” Go down to “Equalization.” After that, a window will show. No matter how it appears, just make sure the entire blue bar is all the way to the top of the window. Once you have done that, click the button that say “OK.” If Audacity picked up any sound, it will now make that sound much louder and you can hear it. If it didn't pick up any sound, you might hear a buzzing or you might hear nothing at all.
You also need to check if you have DVD playback. Find a DVD and put it into your DVD drive if you have one. It doesn't matter if a program called Media Player opens. Just let it try to detect the CD and when and if it shows and error, say “okay” and then close the program.
Open VLC by going to Applications, Multimedia, VLC media player. Go to the Media menu and choose “Open Disc.” Being that you should have a DVD in the drive, make sure the radio button next to “DVD” is selected. Then click on the button that says “Play.” The DVD should start playing.
The next thing you need to check is java. Go to www.pogo.com and try to play any one of the free games that are available on the site.
If the game says that you need to install java, do not follow the instructions on the screen. Instead, simply close the browser windows that are open.
The next part is the trickier part. I have always needed somebody to help me with this. I am only able to write this because I saved the information. He usually has helped me find if the computer is detecting all of my hardware. Hopefully Linux will be detecting all of your hardware. If you follow these steps and everything still isn't working, it is likely that Linux is not detecting your hardware and that you will need to find help elsewhere.
However, you can simply try to run these following commands.
The first thing that you need to do before running any commands is to find “Terminal.” You can usually find this is one of the menus under “Applications.” It may be in “Accessories” or it may be in “System.” It might even be elsewhere. It always depends on your distribution and desktop environment of Linux.
Once you find “Terminal,” open it up. You should see the user name that you chose followed by something similar to “@ubuntu:~$”
If you see something similar to that, you are most likely good to go. Also, you need to make sure that your web browser is closed.
You can copy the following commands, but do not use the Ctrl+C and the Ctrl+V. You need to make sure that you use the edit menu for these to work properly. You can also type these commands into the terminal.
Type or copy:
sudo aptitude install linux-restricted-modules-`uname -r` linux-generic
Then press enter.
If it asks for your password, type in the password that you chose when installing Linux in order to log onto Linux. Your password will not show as being typed, so do not be concerned when it does not show.
If it asks if you'd like to continue, put Y.
Do not be concerned if you see it saying that it is removing anything. This is just part of what is necessary.
Next, copy or type:
sudo apt-get install cheese libv4l-0
Then press enter and type in your password if asked as well as pressing “Y” if asked if you'd like to continue.
Now, type or copy:
sudo apt-get install sun-java6-plugin
As always, give the password if necessary and tell it “Y” if it asks to continue or if you want other files installed.
After this, go to https://help.ubuntu.com/community/RestrictedFormats and find the part of the page that says “Playing Restricted Formats.”
Choose the correct download for the distribution of Linux that you chose to install on your computer. Click on that link and tell it to install everything. Agree to everything and type in your password when necessary.
Once this is done, you need to open the Terminal or the “Konsole” again.
Now type or copy:
sudo /usr/share/doc/libdvdread4/install-css.s
After this, you may want to reboot your computer, though things might work without a reboot.
Now, it is once again time to test everything as stated earlier in this tutorial. Things should now be working fine, though.
You will find that you have also installed a program called “Cheese,” which is a webcam program. If you have a web cam, go to “Applications” then “Graphics” and then open “Cheese Webcam Booth.” If Linux is detecting your webcam, if you have one, Cheese will turn your webcam on and will detect a picture it can take.
It was only thanks to a member in the LiveJournal Linux community that I was able to get this done and now write this tutorial.
If you need more help, you can seek it in the LiveJournal Linux community or in the LiveJournal Ubutntu Users community or at Newbies Linux.
I am in no way an expert at using Linux and am still learning many things. I am only figuring out what each little command means bit by bit and not even understanding all the Linux commands.
However, hopefully this guide helped you set up your distribution of Linux.
Sources:
LiveJournal Linux Community
LiveJournal Ubuntu Users Community
Newbies Linux
Personal Experience
What Brings about Computer registry Errors? Three Factors You May Have a very Slow Laptop
I apologize in advance for this question being so long! I am a college graduate but presently a stay-at-home mother. I had a battery of medical tests performed, which incidentally included an extensive IQ test. I found out several months ago that, although I have what the neurologist called a "slow processor," my IQ is 142!!! He equated it to having a computer with a 512 gig hard drive but 128 megs of RAM. As long as speed isn't an issue, I have tremendous capability. Needless to say, I was completely floored at my IQ score.
I’m considering going back to college for a post-grad degree part-time, but I'm not sure if I should, or what to major in. My child is 5 years old. There are a lot of challenges and the workload is heavy being a divorced mother. But I don't want to waste what nature has given me! Now that I am aware of my high IQ, I feel an obligation to do something significant, leave a positive impact on the world. I previously majored in Animal Behavior, (half psyc and half bio). Research is intriguing, but difficult to find a job without a Doctorate. Any ideas for careers that are similar but have more job availability with a Master's?
I don't know if I should even try at my age (late thirties). The debt incurred would be large. Would I have enough time in the work force before retirement to make the debt worthwhile? I am concerned that maybe I should just focus on my son, who is also gifted. (He's 5 and reading chapter books and doing simple math problems in his head.) If I take time away from focusing on his tutelage for my own schooling and career, I may not be able to be there for him in the way I feel I should to help him reach his full potential.
I’ve never been so troubled and confused. I knew I was smart but never expected to find out that I am a genius! I need solid input. I am looking for opinions from every source I can find. It's difficult to talk to family because I think that if I told many of them about my IQ, they would somehow look at me differently. Humility is considered a great asset in our bunch! Considering the life situation, having a young child, osteoporosis and related health issues, etc., what would you do if you were in my shoes? Go back to college or not, and if so, for which major?
Thanks for reading this lengthy question!
hi Bob,
It is indeed very difficult to tell what is wrong with your computer without knowing what is the scenario is like. Normally a computer starts to act strangely but was normal before is usually due to corruption of O/S, software or infected with virus, spyware and malware. Sometimes overheating can also cause problem like what you mentioned.
When you mentioned the CPU was at 100%, was this indication from the Task Manager window?
If you can provide more details of your hardware and O/S, I might be able to do diagnosis I hope.
_________________
Morning in the Garden is Paradise
Life n Memories
Malacca Daily Photos
Last but not minimum, if you are able to comply with the above steps meticulously, you must be capable of see an obvious improvement for a computer's efficiency. By employing fix blue screen bad pool header software package to repair and clear windows registry, you is going to be capable of guarantee that your laptop or computer is always at its optimum issue.
Easy methods to Stop Registry Errors – Maintaining Your Registry Protected
As someone that has been making Sims 2 content for some time now I often get asked questions about how to fix Sims 2 related issues. There are two that I get asked about most often; An error that comes up while trying to install certain pre-made Sims and meshes not working. Here are fixes to help you solve these two common Sims 2 issues.
This Content Requires Expansion Pack Data That is Not Installed
This is a bug with the packaging system for the Sims 2. Pre-made sims do not require an expansion to appear properly. Their facial characteristics, body type will appear with no issues. However if the clothing requires an expansion it will not appear but the Sim will always make it to your game. There is a work around for this and this guide will walk you through the steps to fix this annoying Sims 2 error.
1. You will need to install the Sims2Pack Clean Installer. This is a wonderful program created to allow you to install content to your game and actually be able to see what you are installing. It can also be used to remove problem files, duplicates, and hacks. You will need to download the latest version and install it. It can be found here: Sims2Pack Clean Installer
2. Once it is installed, right click on the package (The Sim that is giving you issues). You will get a long list of options, click on Open With, Sims2Pack Clean Installer.
Note: Vista Users will be asked for administrative permissin, click allow.
3. Once that is open you will see all the items in that package. Obviously for a Sim, depending on what is packaged you can have anything from the Sim, Hair Mesh, Hair, Clothing, Clothing Mesh, Eyes and so on. If you do not want to install all of the stuff, then you will need to uncheck everything but the sim itself.
How can you tell which one is the Sim? The sim will be a bunch of random numbers and letters like this: 5n34n3n4_3n34n4in5. Mind you this is just an example, the sim package you are looking for will be different.
4. Once you have decided if you are gonna install everything or just the sim, and have unchecked items or left it as is, you need to click the install button.
5. Once the install button has been clicked a new dialog box will appear. This dialog box is very important because here you need to make sure that your sim is going to the right place.
In Windows 9X/ME:
C:\My Documents\EA Games\The Sims 2\Downloads
In Windows 2000/XP (in these versions of Windows, you MUST be sure to put it in the My Documents folder for YOUR user profile. It will only show in the My Documents folder of the user whose profile it is in.):
C:\Documents and Settings\\My Documents\EA Games\The Sims 2\Downloads
Windows Vista
C:\Users\\Documents\EA Games\The Sims 2\Downloads
Look at the default location, and make sure it is where it needs to go to for your particular operating system. If it is not, uncheck the box in the default installation, select an installation folder, click on Browse, find the location of your downloads folder. Once that is situated, click install.
6. After you click install, the item will be installed to your game and you should get a dialog message that says File Successfully Installed. Click okay, then Click Okay again.
7. Go into your game, go to create-a-sim (The sim will not appear in your family bin, you need to go to create-a-sim). Once in create-a-sim, click on your premade sim icon, and then just look for the sim. The sim will not always appear at the beginning, sometimes it can be in the middle or closer toward the end where the Maxis sims are, this is random where it appears.
Meshes Not Working
Another common problem that people seem to have that I get asked about a lot is meshes not working. I often get e-mails saying the mesh did not work, help me, what do I do. Meshes can conflict with other meshes. This is an unfortunate reality of user-made content. I love to download stuff that other people made but sometimes I do cross paths with things that give me issues or do not appear even though I have downloaded the appropriate meshes. The following are steps to fix problems with problem meshes.
1. Most important thing is to download the item again. Sometimes we get hiccups in our connections that disrupt our downloads. I had this happen to me recently when I downloaded the newest Naruto episode only for it to not work and have to download it a second time. Its actually pretty common and can usually be fixed by just downloading the item again.
2. If you downloaded it again and it still did not work, move the mesh to the Saved Sims folder.
In Windows 9X/ME:
C:\My Documents\EA Games\The Sims 2\Saved Sims
In Windows 2000/XP (in these versions of Windows, you MUST be sure to put it in the My Documents folder for YOUR user profile. It will only show in the My Documents folder of the user whose profile it is in.):
C:\Documents and Settings\\My Documents\EA Games\The Sims 2\Saved Sims
Windows Vista
C:\Users\\Documents\EA Games\The Sims 2\Saved Sims
I have found that almost always, that if I have an issue with a mesh not working that if I move it to the Saved Sims folder it will suddenly work. This is because it is conflicting with a mesh that I already have in game. To simply find what mesh is causing the conflicting is a very long and tedious process that requires moving your downloads one by one. This is a painfully exhausting experience that I do not recommend to anyone.
It is very important that if you are still having issues with certain content that you contact the creator. Sending them a nice letter asking them for help goes a long way. Many content creators for Sims 2 not only are creative but know the game very well and are capable of giving advice on how to fix many issues plaguing your game. Another good thing to do is search the web, especially if you get an error message because a lot of times someone else has had that same issue.
Forums at The Sims Resource and Mod The Sims 2 offer lots of useful information on how to fix various issues with the game. Often if you can not find what you are looking for, if you ask them for help, many of them are kind enough to point you in the right direction. The Sims Wiki also contains a great deal of valuable information that can help you.
Content made by the wonderful Sims 2 community is great and adds to the gameplay experience however it should always be used at your own risk. Sometimes in using said content you can and will cross paths with problems, knowing how to fix these issues will save you from having to delete all your downloads and start over.
Windows error messages may be quite frustrating so you need to make sure that you often and usually computer freezes fix to retain your computer's speed and functionality.
most appropriate ways and means of regulating Those heavy Errors Using the Registry Fix
If you have upgraded your PC's operating system to the new Windows Vista, you may have noticed that some of your old software won't run on the new system. While it may be frustrating to not be able to play your favorite game, it is much more problematic if you anti-virus software is rendered useless by an operating system upgrade.
Right now, there are more than 150,000 known computer viruses and thousands of spyware and adware programs that can infect your computer. Most of these can impact your computer's performance and speed or cause a hard drive crash, but some or even more sinister. If your computer becomes infected by a newer breed of virus,it can be used by someone in a remote location to control other computers and your bank account information, credit card numbers and secure passwords can be stolen. Windows Vista comes with its own set of security tools, but they are not a replacement for a good third party anti-virus application.
Symantec, the company that offers the popular Norton Anti-virus software, is compatible with Vista and offers a free 90 day trial for new users. They also offer a complete security package that offers all of the protection of the original antivirus software, in addition to identity theft protection and a two way firewall that prevents outside access to your computer.
Trend Micro is not as well known as Symantec, but they offer much they same software packages as their larger competitor and were recognized as the top security vendor at the 2006 CIO Insight. The Trend Micro Internet Security 2007 package comes with a 90 day free trial, but the stand alone anti-virus software only comes with a 30 day trial period.
Kapersky Anti-Virus 6.0 has recently been reconfigured to work with Windows Vista as well. It provides good anti-virus protection, but there isn't a trial period. Unless you have used their products in the past, Kapersky may not be a good option for people who like to evaluate their software before making a commitment. Kapersky was named a CNet Editors' Choice and a best buy from Computer Shopper magazine.
Windows has also gotten into the anti-virus market with the release of Windows Live OneCare. The benefit of OneCare is the seamless integration with Vista. The downside could be a perceived security weakness in all Microsoft products. The complete security package includes industry standard anti-virus software, ant-spyware, firewall and file backup protection. There is a free 90 day trial available
Fix Vista & Windows 7 dark Screen of genocide Error (BSOD) together with dark shade Fix
many of us possess approach opposite Windows BSOD (Blue screen of death) infamous underline of Windows XP & perspective. Windows 7 may be utterly stable and doesn’t crash with BSOD but Microsoft has not completely get rid of BSODs. Windows 7 can additionally be influenced by means of dark Screens of genocide that simply solidify awake a computers forcing users to glance at nothing some-more than the vacant, dim desktop.
how to fix blue screen of death
To fix dark Screen of genocide of Windows 7 Prevx’s David Kennerley has developed the good app “Black shade Fix” to repair a immeasurable infancy of issues that cause Black Screens.
Black shade repair Pervex
The root means of the ultimate wave of dark Screens of Death has been identified by way of the alteration cutting-edge a Windows handling Systems lock listed of registry keys. information technology appears which a updates expelled this month by means of Microsoft means certain records office keys to be invalidated, the move that, in the turn generated Black Screen of Death errors.
doubt we have been confronting Windows 7 Black Screen of genocide afterwards transfer Black Screen repair and outing it on your system. how to fix a slow computer A reboot is compulsory after you run this utility.Source:http://www.articlesbase.com/operating-systems-articles/fix-vista-error-0xc0000142-with-registry-cleaner-1613520.html




