Type Error in Alloy using Double In Statement - alloy

I am trying to write a predicate that will make all Bananas and Fresh Apples expensive. I am able to achieve one of the conditions but never both. I'm very new to using Alloy, any help would be very much appreciated.
Below is my code, the error is occurring because I'm using a double In Statement but I'm unsure how I could write this without having to use two in statements. The error I receive is "Type Error, this must be a set or relation"
sig Fruit{}
sig Banana, Apple, Pear extends Fruit {}
sig Fresh, Expensive in Fruit{}
pred BananasAndFreshApplesAreExpensive {
Apple in (Expensive & Fresh) + Banana in Expensive
}
run BananasAndFreshApplesAreExpensive

Another way:
all bananas is represented by the set Banana
all fresh apples is represented by the set Fresh & Apple
x is expensive is represented by x in Expensive
So
Banana in Expensive
(Fresh & Apple) in Expensive
or just
Banana + (Fresh & Apple) in Expensive

If I correctly understand what you're trying to do, the code is not failing because you have 2 "in" statements, it's because you're using a union operator ("+") instead of a logical AND ("and" or "&&").
The return from a predicate has to evaluate to TRUE or FALSE.
If you are trying to say the following:
All instances of Apple are expensive and fresh AND
All instances of Banana are expensive
...the following code will do it:
sig Fruit{}
sig Banana, Apple, Pear extends Fruit {}
sig Fresh, Expensive in Fruit{}
pred BananasAndFreshApplesAreExpensive {
Apple in (Expensive & Fresh) and Banana in Expensive
}
run BananasAndFreshApplesAreExpensive
However, if you are trying to say:
Instances of Apple that are fresh are expensive AND
Instances of Banana are expensive
...the following code is one way to do that:
sig Fruit{}
sig Banana, Apple, Pear extends Fruit {}
sig Fresh, Expensive in Fruit{}
pred BananasAndFreshApplesAreExpensive {
(all a: Apple | a in Fresh => a in Expensive) and
Banana in Expensive
}
run BananasAndFreshApplesAreExpensive
Keep in mind, though, that this does not say anything about instances of Apple that are not fresh. In other words, it will allow instances of Apple that are not fresh to be expensive.

Related

Is there something like DuplicateRecordFields for constructors in Haskell? [duplicate]

i am new to Haskell and probably missing something really basic here, but i am not able to re-use same value constructor among different data types.
data Colour = Red | Pink | Orange | Yellow
data Fruit = Apple | Orange | Banana
This produces error saying
Multiple declarations of ‘Orange’
Not sure why this isn't allowed, i have been using OCaml before learning Haskell and was able to define types like this
As a quick exercise try just defining one of your data types and then opening up GHCi to inspect it.
data Colour = Red | Pink | Orange | Yellow
If you use :t in GHCi, it will tell you the type of anything.
> :t Red
Red :: Colour
> :t Orange
Orange :: Colour
So this tells you that your data constructor Orange is really just a function that takes no arguments and produces a value of type Colour.
So what happens if you add a duplicate declaration?
data Colour = Red | Pink | Orange | Yellow
data Fruit = Apple | Orange | Banana
Now you have defined a function Orange that takes no arguments and produces a value of type Colour or a value of type Fruit. This won't work at all! It would be the same as defining your own custom function foo and giving it multiple type signatures:
foo :: Int
foo :: String
foo = "6"
Which obviously doesn't work either.
To get around this, you can define each data type in its own module, and use a qualified import to scope them correctly:
import qualified Colour as C -- Module Colour.hs
import qualified Fruit as F -- Module Fruit.hs
orange1 = C.Orange :: C.Colour
orange2 = F.Orange :: F.Fruit
Now, you might be thinking "The compiler is smart, it should know what Orange I'm talking about when I'm using it." and you'd be partially right. There is an ongoing effort to bring Overloaded or Duplicate record fields into Haskell. There are various other questions of that ilk already defined here, but I'll list a few
references for further reading.
Why DuplicateRecordFields cannot have type inference?
https://github.com/adamgundry/ghc-proposals/blob/overloaded-record-fields/proposals/0000-overloaded-record-fields.rst
https://ghc.haskell.org/trac/ghc/wiki/Records/OverloadedRecordFields/DuplicateRecordFields
There is no particular reason, that is how language was designed. I think the idea was to make sure compiler can infer type for as many expressions as possible. Note that if language will allow to reuse constructors, then you'll have to specify type for show Orange expression - compiler can't infer it anymore. Though now a lot of people don't take this reason seriously, and a lot of modern language extentions do break compiler's ability to infer types for many expressions. So I guess in few years you'll find that your example works already :)

How to use a global variable within a function in Haskell

In section Incorrectly matching against a variable from chapter 3 of real world haskell, there is an example as follows:
-- file: ch03/BogusPattern.hs
data Fruit = Apple | Orange
apple = "apple"
orange = "orange"
whichFruit :: String -> Fruit
whichFruit f = case f of
apple -> Apple
orange -> Orange
The explanation says in case f of part, apple and orange are not treated as global variables as defined before the function declaration. They are local variables.I thought if there is no local variable owning the same name as a global variable, the global variable is not hidden.
The main thing here is that variables in pattern matches always introduce new variables instead of referring to existing ones. Your problem has nothing to do with global vs local variables.
If you want to match the value of f to the value of some variable like apple in a pattern you need to use pattern guards and equality tests. E.g.
whichFruit f
| f == apple = Apple
| f == orange = Orange
You have hit upon irrefutable patterns. As the book mentions, plain variable names and the wild card _ are examples of irrefutable patterns. Another example which will demonstrate irrefutable patterns more clearly:
data Fruit = Apple | Orange deriving (Show)
patternMatch f = case f of
something -> Apple
Now the above program typechecks with an warning. In ghci:
ghci> patternMatch 2
Apple
ghci> patternMatch "hi"
Apple
So basically the variable something is an irrefutable pattern which matches anything.
Now,coming back to your example:
whichFruit :: String -> Fruit
whichFruit f = case f of
apple -> Apple
orange -> Orange
Here the variable apple and orange are irrefutable patterns. They doesn't refer to the global function which you have already created. In fact you can remove the global definition of apple and orange and compile them in order to get an idea. Whatever input you give, you will always get Apple as an answer for the above code (since it is an irrefutable pattern):
ghci > whichFruit "apple"
Apple
ghci > whichFruit "orange"
Apple
ghci > whichFruit "pineApple"
Apple
How to use a global variable within a function in Haskell ?
That's pretty easy actually. Just use them in your function definition.
data Fruit = Apple | Orange deriving (Show)
apple = "apple"
orange = "orange"
giveFruit :: Fruit -> String
giveFruit Apple = apple
giveFruit Orange = orange
In ghci:
ghci> giveFruit Apple
"apple"
ghci> giveFruit Orange
"orange"
Using the variable in the function definition is straight forward.
What should be done if I want the variable to refer to a global
variable owning the same name?
One way would be to use the entire module name to refer to it. Example:
module Fruit where
data Fruit = Apple | Orange deriving (Show)
apple = "apple"
orange = "orange"
giveFruit2 :: Fruit -> String
giveFruit2 apple = Fruit.apple
Right. But there is a local variable apple here owning the same name as the global variable apple, namely apple (duh).
The crucial thing about patterns is that they don't so much compare variables as look out for specific distinguishing features, while simultaneously re-packaging all other information into new variables. The "distinguishing features" are constructor matches (always uppercase1), which don't appear in case f of { apple -> ... }, so simply all the information is passed on in the variable apple.
A more idiomatic example
data Vegetable = Tomato | Potato
data Edible = Fruit Fruit | Vegetable Vegetable
If you want a function to take an Edible argument, it's often useful to deconstruct the type. This might look thus:
canJuice :: Edible -> Bool
canJuice (Fruit Apple) = False
canJuice (Fruit Orange) = True
canJuice (Vegetable Tomato) = True
canJuice (Vegetable Potato) = False
Now, for more complicated data it's awkward to write such lots of canJuice clauses. An alternative would be to first match only on the outmost constructor, and delegate the further work elsewhere:
canJuice :: Edible -> Bool
canJuice (Fruit fruit) = fruitJuicy fruit
canJuice (Vegetable veg) = vegetableJuicy veg
vegetableJuicy :: Vegetable -> Bool
vegetableJuicy Tomato = True
vegetableJuicy Potato = False
For this to work, we needed Haskell's feature of treating any lowercase name appearing in a pattern as a new variable, which takes on the value in the "hole" of our pattern match.
1 There are also infix constructors, the best-known is list-cons (:) (they all start with a colon, like all named constructors start uppercase).

How to write "Show" Typeclass for data

I have a very simple data and I want to use Show Typeclass to give it a nice output.
data Fruit = Apple | Orange Int
instance Show Fruit
where
show Apple = "Hey Apple"
show Orange a = "X number of Orange"
This gives the following error but I don't know how to fix it:
Equations for `show' have different numbers of arguments
You just forgot some parens :)
instance Show Fruit where
show Apple = "Hey Apple"
show (Orange a) = show a ++ " number of Orange"
Patterns like Orange a need parens to disambiguate from something like Apple a where we really have two arguments.

express equivalence between several instances

Suppose I have a sig A in my module that is related to a sig B.
Imagine now that we have the several instances :
A$1 -> B$1 , A$2 -> B$2
and
A$1 -> B$2 , A$2 -> B$1
I would like to express that B$1 and B$2 are equivalent (under certain conditions) such that only this instance would be generated A$1 -> B , A$2 -> B.
One of the solution might be to use the keyword "one" while declaring the sig B, but it won't work in my case, because B have several fields, making B atoms not necessarily equivalent . In short 2 atoms are equivalent only if they have their fields of same values.
Ideally I would like to remove the numbering for B. but still be able to have several atoms B .
The Alloy Analyzer doesn't give you much control over how the subsequent instances are generated (or how to break symmetries), so you typically have to work around those issues at the model level.
For your example, maybe this is the right model
sig B{}
one sig BA extends B {}
sig A {
b: one BA
}
run { #A=2 }
First you say that the two instances you describe are equivalent, although at a superficial level they appear to have distinct values for A$1 and A$2. Then you say "2 atoms are equivalent only if ... their fields [have the] same values". If that's the definition of equivalence, then your two instances are not equivalent; if your two instances are equivalent, then your definition is not capturing what you want.
It sounds as if you mean (1) that B atoms are either (1a) always equivalent, or (1b) equivalent under certain circumstances, and (2) that A atoms are equivalent if their fields all have values which are either identical or equivalent. And as if you want to prohibit equivalent A atoms. If that's so, then your jobs are:
Define a predicate that is true for two B elements if and only if they are equivalent.
Define a predicate for two A elements that is true if and only if they are equivalent.
Define a predicate (or a fact) that specifies that no two A atoms in the instance are equivalent.
If your problem is just that the Analyzer is showing you instances of the model which are not interestingly distinct from each other, then see Aleksandar Milicevic's response.

excel matching data

Hi I have a table with item codes in it eg.
A B C D E
Item 500ml 1000ml 2000ml 4000ml
1 Juice 8819686 8819687
2 Vinegar 8813998 8809981 8809982
3 Ice cream 8805690 8805691 8819815
Then I have another list of the above items (I've placed this next to the above table)
A B
Item Code
500ml Juice 8819686
1000ml Juice 8819687
500ml Vinegar 8813998
1000ml Vinegar 8809981
2000ml Vinegar 8809982
500ml Ice Cream 8805690
1000ml Ice Cream 8805691
2000ml Ice Cream 8819815
4000ml Ice Cream 8809984
I want to know which item code in the list is not appearing in the table above (ie. 8809984 is not in the table).
I tried using =IF(ISNA(MATCH(b2,$B$1:$E$E,0)),"Not Found", "Found"), but not working as it returns "Not Found" for every row.
Thank you
You can just use Countif for what you describe:
=CountIf(Sheet2!$B$1:$E$3,B2)>0
You'll get TRUE or FALSE as a result.
how about this way...
{=sum(if(b2=sheet2!$b$1:$e$3,1,0))}
this return 0 if there is no b2 in the target area, and 1 (or more if there are dups). it is array formula so you type everything except {} and then ctrl+alt+enter instead of regular enter.
once you confirmed that the table has unique entry of b2, then you will use following two formula to find index (assuming you do want to know).
{=sum(if(b2=sheet2!$b$1:$e$3,1,0)*{1,2,3,4})}
{=sum(if(b2=sheet2!$b$1:$e$3,1,0)*{1;2;3})}
top one tells the column, the bottom one tells row.
alternatively you could rearrange the original data somehow, but that's messy too...

Resources