Alloy - comparing in first order logic - alloy

How does one compare the equality of functions in Alloy? Something like:
--[(All x)(Exists y)[R(x,y)]
-- and (All x)(All y)[R(x,y) -> R(y,x)]]
-- =
-- (All x)[R(x,x)] and
assert checkEquality{
( all m: Model, x:m.A| some y:m.A | (y in x.(m.R)) ) and
( all m: Model, x:m.A, y:m.A | (y in x.(m.R) -> x in y.(m.R)) ) =
( all m: Model, x:m.A | (x in x.(m.R))
}

Here's an elementary version. Guessing by the '(All x)(All y)[R(x,y) -> R(y,x)]]' part, you've probably thought of something more special; in that case, please specify your question further.
sig Value {}
pred p1 [x, y: Value] {
// ...
}
pred p2 [x, y: Value] {
// ...
}
assert equ_pred {
all x, y: Value | p1 [x, y] <=> p2 [x, y]
}
check equ_pred

Related

How can I return the primitive data type from polymorphism?

Given some custom sum data type,
data Type = Thing Char | NotThing Char
How can I use == to compare between the Char here and some other Char? As below:
let f = 'a'
NotThing e == f
>>> True
Of course, this code cannot compare between types as NotThing is a separate type to Char.
If x :: Char and y :: Type, then the following expressions (among others) are well-typed:
y == Thing x
y == NotThing x
y `elem` [Thing x, NotThing x]
case y of { Thing x' -> x == x'; NotThing x' -> x == x' }
Probably the last one is closest to what you want. I would abstract slightly and write
extract :: Type -> Char
extract (Thing x') = x'
extract (NotThing x') = x'
because I would expect that to occasionally be useful in other contexts. With that in hand, the following expression is also well-typed:
extract y == x
Of course, you'll want to pick a better name than extract, just like you'll do for Type, Thing, and NotThing.

Remove predicate relations in Alloy

I'm learning how to use Alloy, and I've coded this:
module test/SlotsAndFillers
sig Slot { content: one Filler}
sig Filler { slots: set Slot}
fact AllSlotsAreOwned {
all s:Slot | some x:Filler | s in x.slots
}
fact ImproperParthoodSlots {
all x:Filler | some y, z:Slot | y in x.slots implies z in x.slots and x in z.content
}
fact SlotInheritance {
all x, y : Filler, z, z' : Slot | x != y and z != z' and z in y.slots and x in z.content and z' in x.slots implies z' in y.slots
}
fact SingleOccupancy {
all x:Slot, y:Filler | x in y.slots implies one z:Filler | z in x.content
}
fact MutualOccupancyIsIdentity {
all x, y: Filler, z, z': Slot | x != y and z != z' and
z in y.slots and x in z.content and z' in x.slots and y in z'.content implies x = y
}
pred show() {}
run show
When I execute and show models, in addition to both relations content and slots, the models also have new relations, named $show_x, $show_y and $show_z. By testing, I understood that these relations are present if I add things inside the predicate. But for this code, show is empty and there are still these relations. So I've two questions: where do they come from and how to remove them? I know that I can hide them, but then the models look all (nearly) the same. So I would like to explore different models that uses only my two relations and not new ones.
Do not hesitate to reformulate or retitle this post.
Thanks!
When you are executing a run command followed by a predicate, you are actually generating instances satisfying that predicate.
From my understanding, when the predicate is named, the instance visualizer tries to highlight which elements of the instance satisfy the predicate. In your case, "everything" is conforming to this empty predicate and so the name of your predicate is shown everywhere.
A simple workaround is to simply not name the predicate that you give as parameter to the run command:
module test/SlotsAndFillers
sig Slot { content: one Filler}
sig Filler { slots: set Slot}
fact AllSlotsAreOwned {
all s:Slot | some x:Filler | s in x.slots
}
fact ImproperParthoodSlots {
all x:Filler | some y, z:Slot | y in x.slots implies z in x.slots and x in z.content
}
fact SlotInheritance {
all x, y : Filler, z, z' : Slot | x != y and z != z' and z in y.slots and x in z.content and z' in x.slots implies z' in y.slots
}
fact SingleOccupancy {
all x:Slot, y:Filler | x in y.slots implies one z:Filler | z in x.content
}
fact MutualOccupancyIsIdentity {
all x, y: Filler, z, z': Slot | x != y and z != z' and
z in y.slots and x in z.content and z' in x.slots and y in z'.content implies x = y
}
run {}
EDIT:
It seems that this fix doesn't solve the problem. Indeed quantification variables defined in facts are still displayed by the instance viewer.
The only option left (I can think of) to get rid of them is to manually disable their representation in the Theme Menu.
(for the 3 relations $x,$y, $z, set "show as arcs" to off)

How do I create a dictionary in OCaml that associates to each element of the first list the number of its occurences in the second list?

I have two lists, ["0","1"] and ["0","1","0"], and I want to get a list, [(0,2),(1,1)], - which associates to each element of the first list the number of its occurrences in the second list. I tried this:
let partialSolution =
List.map(
fun x ->
let subsubList = List.for_all (fun y -> (String.compare x y)=0) ) ("0"::("1"::("0"::[]))) in
(x, List.length ( List.filter ( fun z -> z = true) subsubList ) )
) ;;
, but it's not good: it gives me these errors:
# let partialSolution =
# List.map(
# fun x ->
# let subsubList = List.for_all (fun y -> (String.compare x y)=0) )
File "", line 4, characters 73-74:
Error: Syntax error: operator expected.
# ("0"::("1"::("0"::[]))) in
File "", line 4, characters 99-101:
Error: Syntax error
# (x, List.length ( List.filter ( fun z -> z = true) subsubList ) )
# )
File "", line 6, characters 0-1:
Error: Syntax error
# ;;
File "", line 6, characters 2-4:
Error: Syntax error
I would like to understand how I can fix this - I am a total newbie to OCaml.
You're a bit overzealous with the parentheses. The syntax error is caused by an extra closing parentheses after (fun y -> ...).
But you'll still have a type error, since List.for_all returns a bool, true if all items satisfy the predicate and false otherwise. It seems you want to use List.map here instead.
You also don't need to surround every use of :: with parentheses. ("0"::"1"::"0"::[]) is fine, but you can also just reduce this to a simple list literal: ["0"; "1"; "0"]. Additionally, z = true is equivalent to z, though perhaps slightly less readable.
This compiles. I haven't checked whether it actually does what you want though:
let partialSolution =
List.map
begin fun x ->
let subsubList =
List.map
(fun y -> String.compare x y = 0)
["0"; "1"; "0"]
in
(x, List.length (List.filter (fun z -> z) subsubList))
end
Also, if you're using 4.03 or higher you can use String.equal, and if you're using 4.08 you can use Fun.id instead of the ad hoc lambda functions:
let partialSolution =
List.map
begin fun x ->
let subsubList =
List.map (String.equal x) ["0"; "1"; "0"]
in
(x, List.length (List.filter Fun.id subsubList))
end
Or instead of dealing with an intermediate bool list, you could use List.fold_left to do a count directly:
let partialSolution =
List.map
begin fun x ->
let count =
List.fold_left
(fun count y ->
if String.compare x y = 0 then
count + 1
else
count)
0 ["0"; "1"; "0"]
in
(x, count)
end

whats the advantage of using guards in Haskell?

count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+(count_instances x ts)
| otherwise = count_instances x ts
i just want to know whats so good about using guards in this Question ?
A guard can be a way to write only one half of an if-then-else expression; you can omit the else and have a partial function.
-- Leave the function undefined for x /= y
foo x y | x == y = ...
You can do the same with a case statement, but it's more verbose
foo x y = case x == y of
True -> ...
It's also easier to list several unrelated conditions as a set of alternatives than it is with a nested if-then-else or case expressions.
foo x y | p1 x y = ...
foo x y | p2 x y = ...
foo x y | p3 x y = ...
foo x y = ...
vs
foo x y = if p1 x y then ...
else (if p2 x y then ...
else (if p3 x y then ... else ...))
Patterns with guards are probably the most concise way to write code that otherwise would require nested case/if expressions.
Not the least advantage is that a where clause applies to all the guards right hand sides. This is why your example could be even more concise:
count_instances :: (Int)->([Int])->Int
count_instances x [] = 0
count_instances x (t:ts)
| x==t = 1+rest
| otherwise = rest
where rest = count_instances x ts
A guard is haskell's most general conditional statement, like if/then/else in other languages.
Your code shows a straight forward implementation of counting contents of a list equal to a given parameter. This is a good example to learn how haskell's recursion works.
An alternative implementation would be
count_instances :: Int -> [Int] -> Int
count_instances i = length . filter (==i)
that reuses already existing functions from the Prelude module. This is shorter and probably more readable.

group by until changed sequence

I have a big Excel file, which i read with Excel Provider in F#.
The rows should be grouped by some column. Processing crashes with OutOfMemoryException. Not sure whether the Seq.groupBy call is guilty or excel type provider.
To simplify it I use 3D Point here as a row.
type Point = { x : float; y: float; z: float; }
let points = seq {
for x in 1 .. 1000 do
for y in 1 .. 1000 do
for z in 1 .. 1000 ->
{x = float x; y = float y; z = float z}
}
let groups = points |> Seq.groupBy (fun point -> point.x)
The rows are already ordered by grouped column, e.g. 10 points with x = 10, then 20 points with x = 20 and so one. Instead of grouping them I need just to split the rows in chunks until changed. Is there some way to enumerate the sequence just once and get sequence of rows splitted, not grouped, by some column value or some f(row) value?
If the rows are already ordered then this chunkify function will return a seq<'a list>. Each list will contain all the points with the same x value.
let chunkify pred s = seq {
let values = ref []
for x in s do
match !values with
|h::t -> if pred h x then
values := x::!values
else
yield !values
values := [x]
|[] -> values := [x]
yield !values
}
let chunked = points |> chunkify (fun x y -> x.x = y.x)
Here chunked has a type of
seq<Point list>
Another solution, along the same lines as Kevin's
module Seq =
let chunkBy f src =
seq {
let chunk = ResizeArray()
let mutable key = Unchecked.defaultof<_>
for x in src do
let newKey = f x
if (chunk.Count <> 0) && (newKey <> key) then
yield chunk.ToArray()
chunk.Clear()
key <- newKey
chunk.Add(x)
}
// returns 2 arrays, each with 1000 elements
points |> Seq.chunkBy (fun pt -> pt.y) |> Seq.take 2
Here's a purely functional approach, which is surely slower, and much harder to understand.
module Seq =
let chunkByFold f src =
src
|> Seq.scan (fun (chunk, (key, carry)) x ->
let chunk = defaultArg carry chunk
let newKey = f x
if List.isEmpty chunk then [x], (newKey, None)
elif newKey = key then x :: chunk, (key, None)
else chunk, (newKey, Some([x]))) ([], (Unchecked.defaultof<_>, None))
|> Seq.filter (snd >> snd >> Option.isSome)
|> Seq.map fst
Lets start with the input
let count = 1000
type Point = { x : float; y: float; z: float; }
let points = seq {
for x in 1 .. count do
for y in 1 .. count do
for z in 1 .. count ->
{x = float x; y = float y; z = float z}
}
val count : int = 1000
type Point =
{x: float;
y: float;
z: float;}
val points : seq<Point>
If we try to evalute points then we get a OutOfMemoryException:
points |> Seq.toList
System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
at Microsoft.FSharp.Collections.FSharpList`1.Cons(T head, FSharpList`1 tail)
at Microsoft.FSharp.Collections.SeqModule.ToList[T](IEnumerable`1 source)
at <StartupCode$FSI_0011>.$FSI_0011.main#()
Stopped due to error
It might be same reason that groupBy fails, but I'm not sure. But it tells us that we have to use seq and yield to return the groups with. So we get this implementation:
let group groupBy points =
let mutable lst = [ ]
seq { for p in points do match lst with | [] -> lst <- [p] | p'::lst' when groupBy p' p -> lst <- p::lst | lst' -> lst <- [p]; yield lst' }
val group : groupBy:('a -> 'a -> bool) -> points:seq<'a> -> seq<'a list>
It is not the most easily read code. It takes each point from the points sequence and prepends it to an accumulator list while the groupBy function is satisfied. If the groupBy function is not satisfied then a new accumulator list is generated and the old one is yielded. Note that the order of the accumulator list is reversed.
Testing the function:
for g in group (fun p' p -> p'.x = p.x ) points do
printfn "%f %i" g.[0].x g.Length
Terminates nicely (after some time).
Other implementation with bug fix and better formatting.
let group (groupBy : 'a -> 'b when 'b : equality) points =
let mutable lst = []
seq {
yield! seq {
for p in points do
match lst with
| [] -> lst <- [ p ]
| p' :: lst' when (groupBy p') = (groupBy p) -> lst <- p :: lst
| lst' ->
lst <- [ p ]
yield (groupBy lst'.Head, lst')
}
yield (groupBy lst.Head, lst)
}
Seems there is no one line purely functional solution or already defined Seq method which I have overseen.
Therefore as an alternative here my own imperative solution. Comparable to #Kevin's answer but actually satisfies more my need. The ref cell contains:
The group key, which is calculated just once for each row
The current chunk list (could be seq to be conform to Seq.groupBy), which contains the elements in the input order for which the f(x) equals to the sored group key (requires equality).
.
let splitByChanged f xs =
let acc = ref (None,[])
seq {
for x in xs do
match !acc with
| None,_ ->
acc := Some (f x),[x]
| Some key, chunk when key = f x ->
acc := Some key, x::chunk
| Some key, chunk ->
let group = chunk |> Seq.toList |> List.rev
yield key, group
acc := Some (f x),[x]
match !acc with
| None,_ -> ()
| Some key,chunk ->
let group = chunk |> Seq.toList |> List.rev
yield key, group
}
points |> splitByChanged (fun point -> point.x)
The function has the following signature:
val splitByChanged :
f:('a -> 'b) -> xs:seq<'a> -> seq<'b * 'a list> when 'b : equality
Correctures and even better solutions are welcome

Resources