In alloy you can make modules polymorphic on signatures by defining them as arguments in the module definition, e.g.:
module mymodule[sigA,sigB]
In my case, I also want to have predicates about these signatures that might change in the different instantiations of my module. Something like, say,
module mymodule[sigA,predA]
sig B extends sigA {}
pred B[b : B] { ... }
fact { all b : B | predA[b] => predB[b]}
If I just do it like this naively, Alloy complains that it won't typecheck, as parameters to a module are automatically assumed to be signatures. Is there any workaround or some other way to make modules be polymorphic in predicates like this?
Genericity in the module system is indeed limited to signatures parameters. The only workaround (sort of) I know of is exemplified in util/graph for instance, of which I'm pasting an excerpt:
module util/graph[node]
/** graph is rooted at root */
pred rootedAt[r: node->node, root: node] {
node in root.*r
}
As you can see, node is a parameter. If you want to talk about a relation on nodes, then you pass it as a parameter (e.g.: rootedAt). So, you can;t require the existence of a relation on nodes, in addition to the signature node itself, but you can give the module "client" means to reason about fields too.
Related
When a proto and multis are defined in the same module, Type.^lookup('method').candidates returns a list of all multi candidates. However, this appears not to work when the proto lives in a different file/module from the multis.
say Setty.^lookup('grab').candidates; # OUTPUT: ()
Is there any way to find the full list of multi candidates through Raku's introspection? Or is there no alternative to grepping through the source code? (I ask because having a full list of multi candidates applicable to a given proto would be helpful for documentation purposes.)
So far as multi methods go, it's not really to do with being in the same module or file at all. Consider these classes:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
Whenever we compose a class that contains multi methods, we need to attach them to a controlling proto. In the case of Base, this was explicitly written, so there's nothing to do other than to add the multi candidate to its candidate list. Had we not written a proto explicitly in Base, however, then one with an empty candidate list would have been generated for us, with the same end result.
The process I just described is a bit of a simplification of what really happens, however. The steps are:
See if this class has a proto already; if so, add the multi to it
Otherwise, see if any base class has a proto; if so, clone it (in tern cloning the candidate list) and add the multi to that.
Otherwise, generate a new proto.
And step 2 is really the answer to your question. If we do:
say "Base:";
.raku.say for Base.^lookup('m').candidates;
say "Derived:";
.raku.say for Derived.^lookup('m').candidates;
Then the output is:
Base:
multi method m (Base: *%_) { #`(Method|82762064) ... }
Derived:
multi method m (Base: ) { #`(Method|82762064) ... }
multi method m (Derived: ) { #`(Method|82762208) ... }
That is, the candidate list in Base has one entry, and the candidate list in Derived has the entry cloned from Base as well as a new one.
Pretty much everything follows this principle: derived classes reference their base class (and the roles they do), but base classes (and roles) don't know about their descendants.
I have interfaces defined for my typescript server APIs and when defining models through MobX state tree I would like to ensure that the typescript compiler enforces that the model snapshots comply with these interfaces.
So if an additional property gets added to IFoo interface, but is not added to Foo MST model, it would be desirable to have typescript complain about it at compile time.
What is the best way to enforce the above ?
I am aware that I can get a valid typescript interface from the model itself:
type IFoo = typeof Foo.Type
I don't want to use this interface for my server APIs because:
It is not desirable to have things like IObservable, IComplexType etc. in API interfaces which essentially deal with snapshots (plain objects).
Interfaces derived thus also have method signatures for actions which are not desirable.
I had attempted something like:
// IFoo is my server interface
const T = t.model("Foo", {...})
type IT = typeof T.Type;
type ISnapshot<T> = {[K in keyof T]?: T[K];}
export const Foo : IModelType<ISnapshot<IFoo>, IT> = T;
But this does not seem to be working as expected.
The correct answer to go for would be to use the .SnapshotType
Unfortunatelly we can't provide that exactly due to a lack of conditional types in TypeScript.
Up to then you need to define your interface manually :(
Here's the issue where you can track the progress :)
https://github.com/mobxjs/mobx-state-tree/issues/117
You want Foo.SnapshotType
so:
type IFooSnapshot = typeof Foo.SnapshotType
As an interim solution, I have done the following:
import { IType } from "mobx-state-tree";
export type ISchema<T> = {[K in keyof T]: IType<any, any>;}
And while defining my models:
const schema: ISchema<IFoo> = { ... }
export const Foo = t.model("Foo", schema)
This isn't as typesafe as I would have liked (which is why I am not accepting this answer).
However, following this pattern consistently in all models solves my primary purpose ie. if news keys are added to API interfaces (or keys are removed) then typescript will fail to compile if my client models don't have the same keys.
Imagine a series of complex grammars represented as roles, although this simple example is enough to show the conflict:
role Alpha {
token alpha { :i <[A..Z]> }
}
role Digit {
token digit { <[0..9]> }
}
role Either
does Alpha
does Digit {
token either { <alpha> | <digit> }
}
grammar Thingy
does Either
does Alpha
{
token TOP { <alpha> <either>* }
}
my $match = Thingy.parse( '1a3' );
dd $match;
This doesn't work because Perl 6 doesn't untangle the relationships to figure out that the conflict is actually the same thing from the same source:
Method 'alpha' must be resolved by class Thingy because it exists in multiple roles
But, reading S14, I see:
A role may not inherit from a class, but may be composed of other roles. However, this "crony" composition is not evaluated until class composition time. This means that if two roles bring in the same crony, there's no conflict--it's just as if the class pulled in the crony role itself and the respective roles didn't. A role may never conflict with itself regardless of its method of incorporation.
I read that to mean that the roles are applied as late as possible, so the class Thingy would be able to disentangle that Alpha is included in two different parts. I figured this would work something like creating a list of all of the roles that would make up the final class, then applying that list only to the final class. That way, something like Either would mix-in only the things it defined and would rely on the later composition to bring in Alpha.
I ran across this when I was trying to implement grammars for various (IETF) RFCs. Many of them reference the grammars from other RFCs, which makes it impossible for Perl 6 to resolve inheritance by C3. So, I figured that roles would disconnect the relationships. Apparently it doesn't.
Yes, Perl 6 should be able to untangle the inclusion of the same role from different sources.
Simple definitions of a role are:
A role encapsulates some piece of behavior or state that can be shared between classes.
or
A role is a name for a discrete collection of behaviors.
So, let's say we have a Floatable behavior for objects that can be floated on water, and a Sailable behavior for objects that can be sailed. Naturally, objects that can be sailed can be floated. A Sloop is naturally floatable and sailable. There is no conflict in the fact that the same Floatable behavior is conveyed by both Floatable and Sailable roles.
In Perl, this works as expected (it works with Moose as well):
#!/usr/bin/env perl
use v5.24; # why not
use warnings;
package Floatable {
use Moo::Role;
sub float { say "float" }
}
package Sailable {
use Moo::Role;
with 'Floatable';
sub sail { $_[0]->float; say "sail" };
}
package Sloop {
use Moo;
with qw( Floatable Sailable );
}
my $s = Sloop->new;
$s->sail;
This behavior is the intuitively obvious one.
One problem I noticed when looking at the Perl6 documentation for roles is the lack of a simple, one sentence definition:
Roles are in some ways similar to classes, in that they are a collection of attributes and methods. They differ in that roles are also meant for describing only parts of an object's behavior and in how roles are applied to classes. Or to phrase it differently, classes are meant for managing objects and roles are meant for managing behavior and code reuse.
...
Role application differs significantly from class inheritance. When a role is applied to a class, the methods of that role are copied into the class. If multiple roles are applied to the same class, conflicts (e.g. attributes or non-multi methods of the same name) cause a compile-time error, which can be solved by providing a method of the same name in the class.
Apparently, when perl6 encounters two roles that provide the exact same behavior, it thinks of this as a conflict in a way I find unreasonable.
Note the subtle distinction in the following example:
#!/usr/bin/env perl
use v5.24; # why not
use warnings;
package Floatable {
use Moo::Role;
sub float { say "float" }
}
package Sailable {
use Moo::Role;
sub float { say "floating bonds to finance journey "}
sub sail { $_[0]->float; say "sail" };
}
package Sloop {
use Moo;
with qw( Floatable Sailable );
}
my $s = Sloop->new;
$s->sail;
In this case, the conflict is to be expected, because two distinct roles want to claim to provide the same behaviors.
According to wikipedia
Dependency is a relationship that shows that an element, or set of elements, requires other model elements for their specification or implementation.[1] The element is dependent upon the independent element, called the supplier.
So is it not the same as unidirectional association?
Do we use dependency when an operation in one class uses object of the other class as its parameter?
How are unidirectional association and dependency different.
Any example would be very helpful
Dependency :
Indicates that a client element(of any kind, including classes,
packages, use cases, etc) has knowledge of another supplier element,
and a change in supplier can effect the client.
So "dependency" is very broad relationship.Suppose that if a class-object(client) has another class-object(supplier) as a member,if a class-object send a message to another class-object,if a class-object takes another class-object as an parameter from its methods, even if a class(client) is subclass of another class(supplier) there will be dependency since change from supplier will effect clients.
Technically all of those relationships can be shown by "Dependency" line. But some of above relationships already has special notations: such as for superclass-subclass relationship we have generalization relationship.No need to show also "dependency" line because if they have generalization relationship, they have dependency. And we have "association" relationship for class-object(client) who has another class-object as a member [attribute]. So also no need to show extra dependency line in this situation.
Actually "Dependency" is badly defined relationship for class diagrams. But it can be usefull for showing dependency in which UML has no special notation such as :
if you has another class-object(supplier) as a parameter in one of your class(client) methods
if you have dependency to global variables
when you call static methods on another classes.
local variables (which you think you have important dependency)
public class RepositoryManager
{
public UpdatePriceFor(ProductDescription description)
{
Time date = Clock::GetTime();
Money oldPrice =description.GetPrice();
...
}
private IList<Item> itemsList = new List<Item>();
}
So all "associations" are also shows "dependency".But "dependency" is
broad-general-weak relationship.As a rule if there is a special
relationship which is more specific-stronger than dependency
relationship than use it. And lastly use all your relationship
"economically". Show only important ones based on modeler-model reader
perspectives.
[ Source : Adapted from Craig Larman's Applying UML and Patterns book ]
Check Fowlers bliki for further information DependencyAndAssociation
Association means that the two associated entities are linked semantically. Dependency only declares that there is a... well, dependency of some sort. All associations are dependencies, while a dependency does not actually mean association. For example, class 'A' depends on class 'B' if it has a method that takes 'B' and passes it as argument to a function in another class. But if 'A' calls some method of class 'B', it should be modeled as association.
Disclaimer I have read the UML specification and also asked myself this question a number of times. I arrived at at the definition above, but I'm still not sure it is 100% correct.
I am pretty much starting to look into alloy for doing some verification. I am trying to practice into making something for represent programming languages simple structure.
An mapping entity has a program and dependency relations
A program has functions
Functions have lines of code
Dependency relations is an entity that maps 2 lines of code in some function in the program between each other
Here is what I tried to do but the output graph shows a line of code that is linked to a dependency tuple but not matched to the function. I need all lines of code to be in a function and they can be in dependencies or not...
abstract sig mapping{}
sig Dependency extends mapping {dep0,dep1: one line}
one sig Program extends mapping{ F: some function, D: some Dependency }
//mapping entity is composed of Dependency pairs 2 lines of code
//and one program which has functions and dependency pairs
sig function { Line : some line}
//Function is made of line of code
abstract sig line{}
run {}
You should add some facts that will enforce the constraints you have in mind for your model.
For example, to enforce that every line has a corresponding function, you can write something like
fact LinesBelongToFunctions {
all ln: line |
one f: function |
ln in f.Line
}
This fact says that for each line ln there exists exactly one function f such that f.Lines contains line ln.