Dear Maude Abusers, A new alpha release can be accessed at SRI-CSL in: ~eker/public_html/Maude/Alpha85a/ or downloaded from: http://www.csl.sri.com/~eker/Maude/Alpha85a/ Alpha release site authentication: User Name: maudeabuser Password: bughunter This version is a pure alpha release - it is not destined for the Maude website though of course you may redistribute it under the GPL. Because of this I have only made binaries for Linux and Darwin. Bug Fixes ========== (1) Operators op __ : TypeList TypeList -> TypeList [ditto] . op nil : -> EqCondition . op none : -> AttributeSet . were not declared as constructors. Found by Joe Hendrix with his sufficient completeness checker. (2) The declaration op _&_ : Nat Int -> Nat [...] . was missing from fmod INT causing certain integer expressions to have a larger sort than necessary. New features ============= (1) Operator declarations may now take the metadata attribute that was previously reserved for mbs/eqs/rls. Note that like ctor, metadata is attached to the declaration and not the operator. Thus two subsorted overloaded declarations may have different metadata attributes, a metadata attribute is not copied by the ditto attribute and a declaration may have a metadata attribute as well as a ditto attribute: fmod FOO is sorts Foo Bar . subsort Foo < Bar . op f : Foo -> Foo [memo metadata "f on Foos"] . op f : Bar -> Bar [ditto metadata "f on Bars"] . endfm The metadata attribute is copied unchanged by importation and renaming; it may not be explicity mentioned in a renaming. It has no effect on semantics except that it is visible in meta operator declarations (using the existing metadata operator) generated by ascent functions. This feature was requested by Carolyn. (2) The is now alpha quality support for rewriting with external objects and an implementation of sockets as the first such external objects. Configurations that want to communicate with external objects must contain at least one 'portal' where op <> : -> Portal [ctor] . now appears in mod CONFIGURATION . Rewriting with external objects is started by the command erewrite (or erew) which is like frew except is allows messages to be exchanged with external objects that do not reside in the configuration. Currently erewrite has some serious limitations: (a) Limit / gas parameters, and continuation do not work (b) Rewrites that involve messages entering or leaving the configuration do not show up in tracing, profiling or rewrite counts. (c) Bad interactions with break points and debugger. (d) Potential race condition with ^C. Note that erewrite may not terminate just because there are no more rewrite possible - if there are requests made to external objects that have not yet been fulfilled because of waiting for external events from the operating system, the Maude interpreter will suspend until at least one of those events occurs at which time rewriting will resume. While the interpreter is suspended, the erewrite may be aborted with ^C. External objects created by an erewrite do not survive to the next erewrite. If a message to an external object is malformed or inappropriate or the external object is not ready for it, it just stays in the configuration for future acceptance or for debugging purposes. The first example of external objects is sockets, which are accessed using the messages declared in socket.maude : mod SOCKET is pr STRING . inc CONFIGURATION . op socket : Nat -> Oid [ctor] . op createClientTcpSocket : Oid Oid String Nat -> Msg [ctor msg format (b o)] . op createServerTcpSocket : Oid Oid Nat Nat -> Msg [ctor msg format (b o)] . op createdSocket : Oid Oid Oid -> Msg [ctor msg format (m o)] . op acceptClient : Oid Oid -> Msg [ctor msg format (b o)] . op acceptedClient : Oid Oid String Oid -> Msg [ctor msg format (m o)] . op send : Oid Oid String -> Msg [ctor msg format (b o)] . op sent : Oid Oid -> Msg [ctor msg format (m o)] . op receive : Oid Oid -> Msg [ctor msg format (b o)] . op received : Oid Oid String -> Msg [ctor msg format (m o)] . op closeSocket : Oid Oid -> Msg [ctor msg format (b o)] . op closedSocket : Oid Oid String -> Msg [ctor msg format (m o)] . op socketError : Oid Oid String -> Msg [ctor msg format (r o)] . op socketManager : -> Oid [special (...)] . endm Currently only IPv4 TCP sockets are supported - other protocol families and socket types may be added in the future. The external object named by socketManager is a factory for socket objects. To create a client socket, you send socketManager a createClientTcpSocket(socketManager, ME, ADDRESS, PORT) where ME is the name of the object the reply should be sent to, ADDRESS is the name of the server you want to connect to; say "www.google.com", and PORT is the port you want to connect to; say 80 for HTTP connections. You may also specify the name of the server as an IPv4 dotted address or as "localhost" for same machine as Maude is running on. The reply will either be: createdSocket(ME, socketManager, NEW-SOCKET-NAME) or socketError(ME, socketManager, REASON) where NEW-SOCKET-NAME is the name of the newly created socket and REASON is the operating system's terse explanation of what went wrong. You can then send data to the server with: send(NEW-SOCKET-NAME, ME, DATA) which elicits either: sent(ME, socketManager) or closedSocket(ME, socketManager, REASON) Notice that all errors on a client socket are handled by closing the socket. Similarly you can receive data from the server with: receive(NEW-SOCKET-NAME, ME) which elicits either: received(ME, socketManager. DATA) or closedSocket(ME, socketManager, REASON) When you are done with the socket you can close it with closeSocket(NEW-SOCKET-NAME, ME) closedSocket(ME, socketManager, "") Once a socket has be closed, it name may be reused so sending messages to a closed socket can cause confusion and should be avoided. Note that TCP does not preserve message boundries, so sending "ONE" and "TWO" might be received as "ON" and "ETWO". Delimiting message boundries is the responsibility of the next higher level protocol, such as HTTP. The file webClient.maude contains an updated version of the 5 rule HTTP/1.0 client from the "Towards Maude 2.0" paper that is now executable. To have communication between 2 Maude interpreter instances, one of them must take the server role and offer a service on a given port. Generally ports below 1024 are protected. You cannot in general assume that a given port is available for use. To create a server socket, you send socketManager a createServerTcpSocket(socketManager, ME, PORT, BACKLOG) where PORT is the PORT number and BACKLOG is the number of queue requests for connection that you will allow (5 seems to be a good choice). The response is createdSocket(ME, socketManager, SERVER-SOCKET-NAME) or socketError(ME, socketManager, REASON) Here SERVER-SOCKET-NAME refers to a server socket. The only thing you can do with a server socket (other than close it) is accept clients: acceptClient(SERVER-SOCKET-NAME, ME) which elicits acceptedClient(ME, SERVER-SOCKET-NAME, ADDRESS, NEW-SOCKET-NAME) or socketError(ME, socketManager, REASON) Here ADDRESS is the originating address of the client and NEW-SOCKET-NAME is the name of the socket you use to communicate with that client. This new socket behaves just like a client socket for sending and receiving. Note the an error in accepting a client does not close the server socket. You can always reuse the server socket to accept new clients until you explicitly close it. The files factorialServer.maude and factorialClient.maude illustrate a very naive 2 way communication between to Maude interpreter instances. The issues of port availability and message boundries are deliberately ignored (and thus if you are unluck this example could fail) for the sake of illustration. Almost everything in the socket implementation is done in a non-blocking way; so for example if you try to open a connection to some webserver and that webserver takes 5 minutes to respond, other rewriting and transactions happen in the meanwhile as part of the same erewrite. The one exception is DNS resolution which is done as part of the createClientTcpSocket() message handling and which cannot be nonblocking without special tricks. Steven