New Features in Visual Prolog 7.0 AlphaProlog Development Center offers you an oppotunity to try Visual Prolog 7.0 Alpha that is supplied together with the Commercial and Personal Edition of Visual Prolog 6.3. Visual Prolog version 7.0 will extends the language with several new features. PolymorphismVisual Prolog 7.0 introduces (parametric) polymorphism. You can declare parameterized domains. For example: domains binTree{Elem} = node(binTree{Elem} Left, Elem Node, binTree{Elem} Right); leaf(). Such a polymorphic domain replaces a complete range of (non-polymorphic) domains: domains bintree_integer = node(bintree_integer Left, integer Node, bintree_integer Right); leaf(). domains bintree_string = node(bintree_string Left, string Node, bintree_string Right); leaf(). ... Moreover, polymorphic predicates can manipulate the polymorphic data structures. This predicate will insert a node in an ordered binary tree: predicates insert : (Elem NewNode, binTree{Elem} Tree) -> binTree{Elem} NewTree. clauses insert(NewNode, leaf()) = node(leaf(), NewNode, leaf()). insert(NewNode, node(Left, Node, Right)) = NewTree :- NewNode <= Node, !, NewTree = node(insert(NewNode, Left), Node, Right). insert(NewNode, node(Left, Node, Right)) = NewTree :- NewTree = node(Left, Node, insert(NewNode, Right)). This single predicate can insert elements in any kind of binTree's: clauses ppp() :- StrTree1 = insert("AAA", leaf()), StrTree2 = intert("BBB", StrTree1), IntTree1 = insert(17, leaf()), IntTree2 = insert(23, IntTree1), ... Polymorphism guarantees type safety, meaning that you cannot insert an integer into a string tree: clauses ppp() :- StrTree1 = insert("AAA", leaf()), SomeTree2 = insert(23, StrTree1), % type error ... Such errors are detected at compile time. In object-oriented programming languages, it is quite common to create data structures like the binary tree using object as an element type: domains bintree_object = node(bintree_object Left, object Node, bintree_object Right); leaf(). Since any object can be converted to object, you can insert any object in such a binary tree. However, this has certain drawbacks (all stemming from the same cause):
These drawbacks do not exist for polymorphic domains: all the elements in the tree are guarantied to have the same type, and, when you retrieve an element from the tree, it will have exactly that type. (This type can, of course, be object if you like). ListsList domains are polymorphic domains. Therefore, it is possible to "reuse" list predicates for any kinds of lists: predicates isMember : (Elem Elem, Elem* List) determ. clauses isMember(Elem, [Head|Tail]) :- Elem = Head or isMember(Elem, Tail). This predicate can be used on integer lists: isMember(17, [23, 45, 32, 17, 58]) It can also be used on string lists: isMember("aaa", ["asd", "asd", "asd"]) But you cannot use it like this: isMember("aaa", [23, 45, 32, 17, 58]) % type error And lists like this does not exist: L = [23, "aaa", 32, 17, 58] % type error "if-then-else" constructionif-then-else is introduced as a language construction: clauses p(X) = Y :- if X = 1 then Z = 3 else Z = 7 end if, Y = 2*Z. If then else can also be used without the else part: clauses p(X) = Y :- if trace = true() then writef("Started p(%)\n", X) end if, ... Deeply Nested "or"In Visual Prolog 7.0, it will be possible to nest "or" deeply in clauses. clauses p(X) = Y :- (X = 1, !, Z = 3 or Z = 7), Y = 2*Z. Here we have used the keyword "or", but you can also use semi-colon ";". We recommend a careful usage of "or"; it is mainly intended for usage in if-then-else constructions: clauses p(X) :- if X = 1 or X > 17 then ... end if. ForeachNew language construction for each: …, foreach p_nd(X) do write(X), nl() end foreach, … The foreach construction is intended as a replacement for fail loops: …, p_nd(X) write(X), nl() fail. However, the "foreach" construction succeeds, when the iteration is completed. So computation will continue right after the "foreach" construction (rather than in the next clause). …, foreach p_nd(X) do write(X), nl() end foreach, write("I will continue here"), ... "foreach" constructions can also be nested properly: …, foreach p_nd(X) do foreach q_nd(X, Q) do writef("Q = %, ", Q) end foreach, foreach r_nd(X, R) do writef("R = %, ", R) end foreach, writef("\nThat was for X = %\n", X) end foreach ... List ComprehensionVisual Prolog 7.0 introduces a new syntax and improved functionality as a supplement to findall/3. ..., List = [ A || p_nd(A) ], ... The line above corresponds to this: ..., findall(A, p_nd(A), List), ... The new construction is a value, and can be used as such: ..., ppp( [ A || p_nd(A) ] ), ... The functionality has been improved so that you can calculate the values to collect: ..., List = [ pair(A, math::sin(A)) || p_nd(A) ], ... You can also have more calls in the "body": ..., List = [ R || p_nd(A), S = math::sin(A), R = pair(A, S) ], ... Stronger Type System with Regards to SubtypingDomain declarations like this: domains
myType = someType.
will define a sub-type (unless someType is a compound domain or a predicate domain) rather than a synonym type. Values of type "myType" can automatically be used as type "someType", but a value of type "someType" will have to be explicitly converted to type "myType". The purpose of this is to increase the safety of your programs. Consider this little setup: domains styleFlag = integer. color = integer. predicates createWindow : (..., styleFlag Style, color Color). "..." is meant as an abbreviation of a number of other arguments. If "styleFlag" is synonym to "integer", and "color" is also synonym to "integer", then "styleFlag" and "color" are also synonym to each other. Therefore a bogus call like this: clauses
ppp(...) :-
Color = getColor(),
StyleFlag = getStyleFlag(),
createWindow(..., Color, StyleFlag). % bogus
is legal. This is no longer the case: a "color" cannot be used as a "styleFlag" (and vice versa), unless you explicitly convert it. Stronger Treatment of Numerical TypesOne very noticeable consequence of this change is that integer and unsigned are kept much stricter apart from each other. If you have an integer but need an unsigned, you will have to convert it explicitly. Backwards Compatibility IssuesThe following new keywords have been introduced:
This means that they can no longer be used as identifiers (Visual Prolog version 6.2 and 6.3 give a warning about this). The stronger treatment of types might require some changes in your program. Typically change of declarations or insertions of explicit conversions. See also:
|
|
|