How can I make my Grails domain class behave like a Number? - grails

I have a bunch of Grails domain classes that I want to be able to treat as Numbers, Integers in particular. For the most part, they are just numeric values with a few extra properties that are used as meta-data. Here's an example:
class Score {
String meaning
Integer value
static hasMany = [responses:Response]
static constraints = {
meaning blank: false, maxSize: 100, unique: true
value min: 1, unique: true // Assume we're using a base-1 ranking system, where 1 is the lowest
}
}
I tried to add #Delegate to the value field, but it didn't seem to have any impact: I still couldn't do 7 + myScore. All I get is missing method exceptions because Integer doesn't have a signature matching plus(Score).
What is the correct way to go about doing this, since #Delegate doesn't seem to work?
Note: I also have a need to turn my domain classes into various Collections with meta data, but I expect it will be the same solution.

I'm imagining everyone has moved on, now that this question is over a year and a half old, but still, I'm surprised that no one offered up Groovy categories as a solution. Indeed, it seems to me that categories are the most natural solution to this problem. Without changing the "Grailsiness" of the original domain class, you can still instill the desired numeric behavior relatively easily.
First define the category class:
class ScoreCategory {
static asType(Score s, Class newClass) {
switch (newClass) {
case Integer.class:
case Integer.TYPE:
case Number.class: return s?.value ?: 0
default: throw new GroovyCastException("Cannot cast to ${newClass}")
}
}
static boolean equals(Score me, def you) {
you instanceof Score && me as int == you as int
}
static Score plus(Score a, b) { plusImpl(a, b) }
static Score plus(Score a, Number b) { plusImpl(a, b) }
static Score plus(Number a, Score b) { plusImpl(a, b) }
private static plusImpl(a, b) { new Score(value: (a as int) + (b as int)) }
static Score minus(Score a, b) { minusImpl(a, b) }
static Score minus(Score a, Number b) { minusImpl(a, b) }
static Score minus(Number a, Score b) { minusImpl(a, b) }
private static minusImpl(a, b) { a + -b }
static Score multiply(Score a, Number b) { multImpl(a,b) }
static Score multiply(Number a, Score b) { multImpl(a,b) }
private static multImpl(a,b) { new Score(value: (a as int) * (b as int)) }
static Integer div(Score a, b) { (a as int).intdiv(b as int) }
static Score div(Score a, Number b) { new Score(value:(a as int).intdiv(b as int)) }
static Score negative(Score a) { new Score(value: -(a as int)) }
static Score abs(Score a) { new Score(value: (a as int).abs())}
}
Then, at some suitably global place in the application declare the mixins:
Number.metaClass.mixin ScoreCategory
Score.metaClass.mixin ScoreCategory
After all this, as demonstrated below, Score objects should now behave like numeric quantities:
def (w, x, y, z) = [54, 78, 21, 32]
def (s1, s2) = [new Score(value:w), new Score(value:x)]
assert (s1 + s2) == new Score(value: w + x)
assert (s1 + y) == new Score(value: w + y)
assert (z + s2) == new Score(value: z + x)
assert (s1 - s2) == new Score(value: w - x)
assert (s1 - y) == new Score(value: w - y)
assert (z - s2) == new Score(value: z - x)
assert (s1 * y) == new Score(value: w * y)
assert (z * s2) == new Score(value: z * x)
assert (s2 / s1) == x.intdiv(w)
assert (s1 / y) == new Score(value: w / y)

You answer can be operator overloding. Here you are overloading the plus method to operate with integers and doubles:
class Score {
...
int plus(int otherValue){
return otherValue + value
}
double plus(double otherValue){
return (value as double) + otherValue
}
// And you can avoid my pitfall overriding asType method
Object asType(Class clazz) {
if (clazz == Integer) {
return value
}
else if(class == Double){
return value as Double
}
else {
super.asType(clazz)
}
}
}
assert new Score(value: 4) + 15 == 19
assert new Score(value: 4) + 15.32 == 19.32
assert 15.32 + (new Score(value: 4) as Double) == 19.32
assert 15 + (new Score(value: 4) as Integer) == 19

Add an overload for the plus operator on the Number metaclass:
Number.metaClass.plus = { Score s -> delegate + s.value }
Add this in BootStrap.groovy in your app, or in doWithDynamicMethods in a plugin.
Edit:
As pointed out in the comments, this doesn't work if the Score is on the left side of the operation. Add a plus method to the Score class to handle that:
Number plus(Number n) { value + n }

You can also extend Number.
class Score extends Number {
Integer value
public int intValue() { return value }
public double doubleValue() { return value }
public long longValue() { return value }
public float floatValue() { return value }
}
Score sc = new Score( value: 5 );
println 10 + sc

Related

Using methods inside loop invariants in Dafny

I'm trying to prove the simple gcd algorithm in Dafny, so I wrote the following, but it seems I can not use the method divides inside the loop invariants:
method divides(d: int, x: int) returns (result: bool)
requires d > 0
requires x > 0
ensures (result == true ) ==> (exists q : int :: (d * q == x))
ensures (result == false) ==> (forall q : int :: (d * q != x))
{
// code omitted
}
method gcd(a: int, b: int) returns (result: int)
requires a > 0
requires b > 0
ensures (forall d : int :: ((exists q1 : int :: q1 * d == a) && (exists q2 :: (q2 * d == b))) ==>
(exists q3 : int :: (q3 * d == result)))
{
var x := a;
var y := b;
var fuel := a+b;
while ((x != y) && (fuel > 0))
decreases fuel
invariant x > 0
invariant y > 0
invariant (forall d : int :: (divides(d,x) && divides(d,y)) ==> (divides(d,a) && divides(d,b)))
{
// code omitted
}
return x;
}
Is there anyway to use a divides method/function/macro inside invariants?
Unlike methods, functions can appear in expressions. You can create a function:
function div(d: int, x: int): bool
{
if (d != 0 && x % d == 0) then true else false
}
Then in your method divides, you can have
ensures result == div(d,x)
and in your method gcd you can use the function div in your invariant.
Note, from the Dafny guide: One caveat of functions is that not only can they appear in annotations, they can only appear in annotations. Functions are never part of the final compiled program, they are just tools to help us verify our code.

Dafny. Pairs with bools do not equal

Why are these two failing in Dafny?
lemma test(x : (int, bool)) {
assert x == (x.0, true) || x == (x.0, false);
}
lemma test''(v : int, x : (int, bool))
requires x.0 == v;
{
assert x == (v, true) || x == (v, false);
}
https://rise4fun.com/Dafny/DtDMdm
I'm guessing this has to do with the internal boxing of booleans for the generic types that tuples can contain. In any case, here's a simple workaround:
lemma test(x : (int, bool)) {
var (i, b) := x;
assert x == (x.0, true) || x == (x.0, false);
}
Rustan

What does code outside a Dafny class verify, but not when encapsulated?

Some code that verifies outside of a Dafny class fails to verify when encapsulated. I'm wondering (1) why, and (2) how to get the best of both worlds: encapsulation/abstraction and verification. The code models a "relation" as a pair: a domain set and a set of pairs over the domain set. Two versions are presented below. The first verifies, the second does not.
The code defines a validity condition that requires that the pairs in the pair set actually be over the domain. It defines a predicate, isFunction, that returns true if the "relation" so modeled is single-valued. This is the predicate that verifies in one case but not in the other. The code, in the Main routine, then verifies that ( dom = {1,2,3,4}, pairs = { (1,1), (2,2), (3,3), (4,4 ) } ) is single-valued (a function). However, when I encapsulate the domain and pairs sets in a class, and make predicates into member functions, the same code in Main no longer verifies.
UNENCAPSULATED VERSION:
/*
Represent a finite binary relation on a set, S,
as a pair: the set S and a set of pairs (to be
drawn from S)
*/
type relationS<T> = (set<T>,set<(T,T)>)
/*
A de-facto Valid() predicate that checks that that each
value in each pair in pairs is a member ofthe domain set.
*/
function method relS<T(!new)>(dom: set<T>, pairs: set<(T,T)>):
relationS<T>
requires forall x, y :: (x, y) in pairs ==> x in dom && y in dom
{
(dom, pairs)
}
/*
Projection function: Given a relation on S, return its co/domain set.
*/
function method domS<T>(r: relationS<T>): set<T>
{
r.0
}
/*
Projection function: Given a relation on S, return its set of pairs.
*/
function method pairsS<T>(r: relationS<T>): set<(T,T)>
{
r.1
}
/*
Return true iff the relation is single-valued (a function)
*/
predicate isFunctionS<T>(r: relationS<T>)
{
forall x, y, z :: x in domS(r) && y in domS(r) && z in domS(r) &&
(x, y) in pairsS(r) &&
(x, z) in pairsS(r) ==>
y == z
}
method Main()
{
var d := {1, 2, 3, 4};
var h := { (1,1), (2,2), (3,3), (4,4) };
var r1 := relS(d,h);
assert isFunctionS(r1); // Verifies
}
ENCAPSULATED VERSION (sorry for slightly different identifiers)
/*
Abstraction of a finite binary relation on a
set, S. Underlying representation is a pair:
the domain set, S, and a set of pairs over S.
*/
class binRelationS<T(!new,==)>
{
var d: set<T>;
var p: set<(T,T)>;
predicate Valid()
reads this;
{
forall x, y :: (x, y) in p ==> x in d && y in d
}
/*
Constructor requires that all values appearing in
any of the pairs in p be in d. That is, the pairs
in p must represent a relation on domain, d.
*/
constructor(dom: set<T>, pairs: set<(T,T)>)
requires forall x, y ::
(x, y) in pairs ==> x in dom && y in dom;
ensures Valid();
{
d := dom;
p := pairs;
}
function method dom(): set<T>
requires Valid();
reads this;
ensures Valid();
{
d
}
function method rel(): set<(T,T)>
requires Valid();
reads this
ensures Valid();
{
p
}
/*
Return true iff the relation is single-valued (a function)
*/
predicate isFunction()
requires Valid();
reads this;
ensures Valid();
{
forall x, y, z ::
x in d && y in d && z in d &&
(x, y) in p && (x, z) in p ==>
y == z
}
}
method Main()
{
var d := {1, 2, 3, 4};
var h := { (1,1), (2,2), (3,3), (4,4) };
var r := new binRelationS(d,h);
assert r.isFunction(); // assertion violation
}
You are simply missing a postcondition from the constructor.
ensures d == dom && p == pairs
This is necessary since, like methods, the bodies of constructors are not revealed to callers. So Main has no idea what the constructor does other than what's in its specification.

How to find out if a z3_ast corresponds to a clause?

I am using Z3 with c api. Is it possible to find out if a given Z3_ast variable corresponds to a clause like or_b1_b2 bellow?
Z3_ast or_b1_b2 = mk_binary_or(c,mk_bool_var(c,"b1"),mk_bool_var(c,"b2"));
Thank you
Yes, The Z3 API provides several functions for inspecting/traversing ASTs.
The Z3 API is minimalist, but it has all necessary ingredients for writing function such as: is_propositional_variable, is_literal, and is_clause. Here is an example:
// Return true if the given ast is an application of the given kind
int is_app_of(Z3_context c, Z3_ast a, Z3_decl_kind k) {
if (Z3_get_ast_kind(c, a) != Z3_APP_AST)
return 0;
return Z3_get_decl_kind(c, Z3_get_app_decl(c, Z3_to_app(c, a))) == k;
}
// Return true if the given ast is an OR.
int is_or(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_OR);
}
// Return true if the given ast is a NOT.
int is_not(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_NOT);
}
// Return true if the given ast is an application of an unintepreted symbol.
int is_uninterp(Z3_context c, Z3_ast a) {
return is_app_of(c, a, Z3_OP_UNINTERPRETED);
}
// Return true if the given ast is a uninterpreted constant.
// That is, it is application (with zero arguments) of an uninterpreted symbol.
int is_uninterp_const(Z3_context c, Z3_ast a) {
return is_uninterp(c, a) && Z3_get_app_num_args(c, Z3_to_app(c, a)) == 0;
}
// Return true if the given ast has Boolean sort (aka type).
int has_bool_sort(Z3_context c, Z3_ast a) {
return Z3_get_sort_kind(c, Z3_get_sort(c, a)) == Z3_BOOL_SORT;
}
// Return true if the given ast is a "propositional variable".
// That is, it has Boolean sort and it is uninterpreted.
int is_propositional_var(Z3_context c, Z3_ast a) {
return is_uninterp_const(c, a) && has_bool_sort(c, a);
}
// Return true if the given ast is a "literal".
// That is, it is a "propositional variable" or the negation of a propositional variable.
int is_literal(Z3_context c, Z3_ast a) {
if (is_propositional_var(c, a))
return 1;
if (is_not(c, a))
return is_propositional_var(c, Z3_get_app_arg(c, Z3_to_app(c, a), 0));
return 0;
}
// Return true if the given ast is a "clause".
// That is, it is a literal, or a disjuction (OR) of literals.
int is_clause(Z3_context c, Z3_ast a) {
if (is_literal(c, a)) {
return 1; // unit clause
}
else if (is_or(c, a)) {
unsigned num;
unsigned i;
num = Z3_get_app_num_args(c, Z3_to_app(c, a));
for (i = 0; i < num; i++) {
if (!is_literal(c, Z3_get_app_arg(c, Z3_to_app(c, a), i)))
return 0;
}
return 1;
}
else {
return 0;
}
}

F# How to Percentile Rank An Array of Doubles?

I am trying to take a numeric array in F#, and rank all the elements so that ties get the same rank. Basically I'm trying to replicate the algorithm I have below in C#, but just for an array of doubles. Help?
rankMatchNum = 0;
rankMatchSum = 0;
previousScore = -999999999;
for (int i = 0; i < factorStocks.Count; i++)
{
//The 1st time through it won't ever match the previous score...
if (factorStocks[i].factors[factorName + "_R"] == previousScore)
{
rankMatchNum = rankMatchNum + 1; //The count of matching ranks
rankMatchSum = rankMatchSum + i + 1; //The rank itself...
for (int j = 0; j <= rankMatchNum; j++)
{
factorStocks[i - j].factors[factorName + "_WR"] = rankMatchSum / (rankMatchNum + 1);
}
}
else
{
rankMatchNum = 0;
rankMatchSum = i + 1;
previousScore = factorStocks[i].factors[factorName + "_R"];
factorStocks[i].factors[factorName + "_WR"] = i + 1;
}
}
Here's how I would do it, although this isn't a direct translation of your code. I've done things in a functional style, piping results from one transformation to another.
let rank seq =
seq
|> Seq.countBy (fun x -> x) // count repeated numbers
|> Seq.sortBy (fun (k,v) -> k) // order by key
|> Seq.fold (fun (r,l) (_,n) -> // accumulate the number of items seen and the list of grouped average ranks
let r'' = r + n // get the rank after this group is processed
let avg = List.averageBy float [r+1 .. r''] // average ranks for this group
r'', ([for _ in 1 .. n -> avg]) :: l) // add a list with avg repeated
(0,[]) // seed the fold with rank 0 and an empty list
|> snd // get the final list component, ignoring the component storing the final rank
|> List.rev // reverse the list
|> List.collect (fun l -> l) // merge individual lists into final list
Or to copy Mehrdad's style:
let rank arr =
let lt item = arr |> Seq.filter (fun x -> x < item) |> Seq.length
let lte item = arr |> Seq.filter (fun x -> x <= item) |> Seq.length
let avgR item = [(lt item) + 1 .. (lte item)] |> List.averageBy float
Seq.map avgR arr
I think that you'll probably find this problem far easier to solve in F# if you rewrite the above in a declarative manner rather than in an imperative manner. Here's my off-the-top-of-my-head approach to rewriting the above declaratively:
First we need a wrapper class to decorate our items with a property carrying the rank.
class Ranked<T> {
public T Value { get; private set; }
public double Rank { get; private set; }
public Ranked(T value, double rank) {
this.Value = value;
this.Rank = rank;
}
}
Here, then, is your algorithm in a declarative manner. Note that elements is your input sequence and the resulting sequence is in the same order as elements. The delegate func is the value that you want to rank elements by.
static class IEnumerableExtensions {
public static IEnumerable<Ranked<T>> Rank<T, TRank>(
this IEnumerable<T> elements,
Func<T, TRank> func
) {
var groups = elements.GroupBy(x => func(x));
var ranks = groups.OrderBy(g => g.Key)
.Aggregate(
(IEnumerable<double>)new List<double>(),
(x, g) =>
x.Concat(
Enumerable.Repeat(
Enumerable.Range(x.Count() + 1, g.Count()).Sum() / (double)g.Count(),
g.Count()
)
)
)
.GroupBy(r => r)
.Select(r => r.Key)
.ToArray();
var dict = groups.Select((g, i) => new { g.Key, Index = i })
.ToDictionary(x => x.Key, x => ranks[x.Index]);
foreach (T element in elements) {
yield return new Ranked<T>(element, dict[func(element)]);
}
}
}
Usage:
class MyClass {
public double Score { get; private set; }
public MyClass(double score) { this.Score = score; }
}
List<MyClass> list = new List<MyClass>() {
new MyClass(1.414),
new MyClass(2.718),
new MyClass(2.718),
new MyClass(2.718),
new MyClass(1.414),
new MyClass(3.141),
new MyClass(3.141),
new MyClass(3.141),
new MyClass(1.618)
};
foreach(var item in list.Rank(x => x.Score)) {
Console.WriteLine("Score = {0}, Rank = {1}", item.Value.Score, item.Rank);
}
Output:
Score = 1.414, Rank = 1.5
Score = 2.718, Rank = 3
Score = 2.718, Rank = 3
Score = 2.718, Rank = 3
Score = 1.414, Rank = 1.5
Score = 3.141, Rank = 5
Score = 3.141, Rank = 5
Score = 3.141, Rank = 5
Score = 1.618, Rank = 8
Note that I do not require the input sequence to be ordered. The resulting code is simpler if you enforce such a requirement on the input sequence. Note further that we do not mutate the input sequence, nor do we mutate the input items. This makes F# happy.
From here you should be able to rewrite this in F# easily.
This is not a very efficient algorithm (O(n2)), but it's quite short and readable:
let percentile arr =
let rank item = ((arr |> Seq.filter (fun i -> i < item)
|> Seq.length |> float) + 1.0)
/ float (Array.length arr) * 100.0
Array.map rank arr
You might mess with the expression fun i -> i < e (or the + 1.0 expression) to achieve your desired way of ranking results:
let arr = [|1.0;2.0;2.0;4.0;3.0;3.0|]
percentile arr |> print_any;;
[|16.66666667; 33.33333333; 33.33333333; 100.0; 66.66666667; 66.66666667|]
Mehrdad's solution is very nice but a bit slow for my purposes. The initial sorting can be done 1 time. Rather than traversing the lists each time to get the number of items < or <= the target, we can use counters. This is more imperative (could have used a fold):
let GetRanks2 ( arr ) =
let tupleList = arr |> Seq.countBy( fun x -> x ) |> Seq.sortBy( fun (x,count) -> x )
let map = new System.Collections.Generic.Dictionary<int,float>()
let mutable index = 1
for (item, count) in tupleList do
let c = count
let avgRank =
let mutable s = 0
for i = index to index + c - 1 do
s <- s + i
float s / float c
map.Add( item, avgRank )
index <- index + c
//
map

Resources