Use Macaulay2 to show that a quotient ring is a field - abstract

I am new to Macaulay2. I tried to use the following command to show that a quotient ring S=ZZ_977[x]/<7x^11+4x^5-23x^4+x-27> is a field:
i2 : S = ZZ[x]/<7*x^11+4*x^5-23*x^4+x-27>
o2 = S
IsField S
But it doesn't work. I looked it up on internet but they don't cover this part. Can someone help? Thanks!

The command (or method in M2 speak) you're looking for is isField rather than IsField.
i1 : R = ZZ[x];
i2 : I = ideal(7*x^11+4*x^5-23*x^4+x-27);
o2 : Ideal of R
i3 : S = R/I;
i4 : isField S
o4 = false
i5 : isField (ZZ/2)
o5 = true
But there is (or at least was as of February 2014) a major caveat about using this internal M2 method for testing whether a quotient ring is a field (alternately testing the maximality of the ideal).
More generally, the applicable rules from the Macaulay2 style guide for naming methods and variables are
Names representing methods must be verbs and written in mixed case
starting with lower case.
The prefix "is" should be used for Boolean variables and methods.

Related

Office Addin: Excel Depth First Search

tl;dr I am having problems with executing a recursive function on an Excel sheet. I will provide as much detail to my problem below as possible but I would appreciate a simple, working async recursive example unrelated to the specific domain/problem I am trying to solve as that might be easier
Problem Context
I am trying to build an add in (task pane) in order to linearize multi-variable analysis (i.e. what if analysis) and constraint solving in spread sheets. My hypothesis is that the inherently two dimensional grid of spreadsheets doesn't scale well as the number of variables grow. I would like to try to surface this functionality through an integrated query language.
Because Excel doesn't allow me to tap into it's interpreter, I need to copy the chain of formulas to cells that are out of view, run my computations there and then copy the results to where the user wants them.
This requires me to recursively explore the formula in question and copy all the nested formulas that may be effected by the variables in question.
For example if I have the following structure.
A7 -> IF(A5>0, A4, A3)
A5 -> A1 + A2
A4 -> A1 + 10
A3 -> A2 + 10
A1 -> 10
A2 -> 20
I start at the target formula and explore the formulas and copy them to a new location. As I copy them, I build a new environment that tell me where to look. i.e.
IF(A5>0, A4, A3)
-- A5
-- A1
-- A2
copy(A5, copyTo = B5, env(A5 -> B5))
-- A4
-- A1
copy(A4, copyTo = B4, env(A5 -> B5, A4 -> B4))
-- A3
-- A2
copy(A3, copyTo = B3, env(A5-> B5, A4-> B4))
new_formula = replaceCells(A7, env) // this will return IF(B5>0, B4, B3)
copy(A7, copyTo=B7, env)
So tl;dr is it's depth first search + environment accumulation, which is normally very simple to do
Actual Problem
However I am having a difficult time wrapping my head around Officejs's concurrency model. Because each recursive call gets executed asynchronously, mutating the environment becomes problematic (while there aren't any race conditions here, the bindings from each depth needs to be present at the time of execution of the one above to allow for correct rewriting
When my first call to this function returns unfortunately a lot of the bindings are missing. I tried solving this issue with both async/await and the Promise API to no result. What is the proper way of going about this? (I am 100% sure this is a concurrency issue. Not only it makes sense but this code works in Google AppScript, where the concurrency model is much more limited).
P.S. You might ask, "if you want this to execute sequentially, why is it async?" -> It's because I need to load in the formulas in the target cell which requires me to sync the context.
P.S. 2: I have also read Avoid using the context.sync method in loops but can't seem to find a way around it.
async function exploreAndCopy(
context: Excel.RequestContext,
currentWorksheet : Excel.Worksheet,
source: string,
target : string,
row : string,
column : number,
env: Map<string, string>) {
let rx = currentWorksheet.getRange(target);
rx.load()
await context.sync();
let cellFormulas = rx.formulas;
if (cellFormulas.length > 0){
var f : string = cellFormulas[0][0]
var newFormula = f.replace(source, "A29")
//Get the referenced cells
let cells : string[] = newFormula.split(/[^A-Za-z0-9]/)
cells = cells.filter(s => s.match(/^(?=.*[a-zA-Z])(?=.*[0-9])/));
//remove dublicates
cells = cells.filter((item, index) => cells.indexOf(item) === index);
for(var c of cells){
// ATTEMP #1
await exploreAndCopy(context, currentWorksheet, source, c, row, column + 1 + cells.indexOf(c), env)
// ATTEMPT #2
exploreAndCopy(context, currentWorksheet, source, c, row, column + 1 + cells.indexOf(c), env).then( p =>
env.forEach((value: string, key: string) => {
newFormula = newFormula.replace(key, value)
})
); // will mutate the env
// Also tried Promises.all
await context.sync();
}
}
await context.sync();
//replace everything in the map
var finalFormula = newFormula
env.forEach((value: string, key: string) => {
finalFormula = finalFormula.replace(key, value);
});
//set env
env.set(target, row + column)
//override
var targetCell = currentWorksheet.getRange(row + column)
targetCell.formulas = [[finalFormula]]
}
Appreciate any recommendations you might have

Why doesn't simple integer counterexample occur in Alloy?

I am trying to model a relationship between a numeric variable and a boolean variable, in which if the numeric variable is in a certain range then the boolean variable will change value. I'm new to Alloy, and am having trouble understanding how to constrain my scope sufficiently to yield the obvious counterexample. My code is as follows:
open util/boolean
one sig Object {
discrete : one Bool,
integer : one Int
}
fact { all o : Object | o.integer > 0 and o.integer < 10 }
fact { all o : Object | o.integer > 5 iff o.discrete = False }
assert discreteCondition { all o : Object | o.discrete = True }
check discreteCondition for 1000
Since o.integer is integer-values and ranges from 0 to 10, it could only be one of 10 different choices. And I specified that each Object should only have one integer and one discrete. So it seems reasonable to me that there are really only 10 cases to check here: one case for each value of integer. And yet even with 1000 cases, I get
No counterexample found.
If I remove the integer variable and related facts then it does find the counterexample almost immediately. I have also tried using other solvers and increasing various depth and memory values in the Options, but this did not help, so clearly my code is at fault.
How can I limit my scope to make Alloy find the counterexample (by iterating over possible values of the integer)? Thanks!
By default, the bitwidth used to represent integers is 4 so only integer in the range [-8,7] are considered during the instance generation, and so, due to integer overflows, your first fact is void (as 10 is outside this range).
To fix the problem, increase the bitwidth used to at least 5:
check discreteCondition for 10 but 5 Int.
Note that a scope of 1000 does not mean that you consider 1000 case in your analysis. The scope is the maximum number of atoms present in the generated instance, typed after a given signature. In your case you have only one signature with multiplicity one. So analyzing your model with a scope of 1 or 10000 doesn't change anything. There'll still be only one Object atom in the instance generated.
You might want to check this Q/A to learn more about scopes Specifying A Scope for Sig in Alloy

Expressing rules in B-Method

I'm writing some specifications of a system in B-method. I have the following variables which are subsets of a general set:
First Notation:
a :={x,y,z,v}
b :={x,y,z}
I want to state a rule that whenever something exists in set "b", it also exists in set "a" which helps writing the above specifications as the following:
second Notation:
a :={v}
b :={x,y,z}
Explanation of second notation: I want the machine to infer that a :={x,y,z,v} from a :={v}, b :={x,y,z}, and the rule.
How can I express the rule so I avoid the first notation and instead write the second notation?
I tried the following but it didn't work
INITIALISATION
a :={v} &
b :={x,y,z}
ASSERTIONS
!x.(x:b => x:a)
First of all, the predicate !x.(x:b => x:a) can be more easily expressed just by b<:a.
It's not clear to me what exactly you want to express: Should b always be a subset of a or just in the initialisation?
If always, the INVARIANT would be the correct location for that. ASSERTIONS are similar but should be an implication by the other invariants.
But then you must explicitly ensure that in your initialisation.
Another point which is unclear to me is what you mean by "infer". Do you just not want to specify the details?
An initialisation where you assign a set with one element more than b could look like the following (assuming that a and b contain elements of S):
INITIALISATION
ANY v,s
WHERE
v:S
& s<:S
THEN
a := s\/{v}
|| b := s
END
(Disclaimer: I haven't actually tested it.)
If a should always be larger than b, you could add something like v/:s.
Your description does not make it clear what exactly you want to achieve.
Another approach would use the "becomes such substitution" (but in my opinion it is less readable):
INITIALISATION
a,b :( a:S & b:S &
b={x,y,z} &
#x.( x:S & a=b\/{x} ))
First, and foremost, the B machine does not infer anything by itself. It provides a language where the user can express properties and a mechanism that generates proof obligations that must be successfully processed by the prover (automatically or with human assistance) to guarantee that the properties hold.
In your example, if you want to express that every element of set bb is always an element of set aa, then as observed by danielp, just write
bb <: aa
Next, if you want to write that aa apossesses an element that is not in bb, then you can express it as
aa /= bb & not(aa = {})
or as
#(elem).(elem : S & elem : bb & not(elem : aa))
If you rather want to express that the specific value vv is in aa but not in bb, then the following applies
vv : bb & not(vv : aa)
These expressions may be used at several locations of the B machine, depending whether you want to assert properties on parameters, constants or variables.
For instance, say you have a machine with two variables va and vb, where both are sets of elements of a given set s1, and that you want they are initialized in such a way that every element of vb is also an element of va, and that there exists an element of va that is not in vb. Observe first that this means that vb is a strict subset of va.
INITIALISATION
ANY inia, inib WHERE
inia <: s1 & inib <: s2 & inib <<: inia
THEN
va := inia || vb := inib
END

Behavior of `=` in alloy fact

I was experimenting with alloy and wrote this code.
one sig s1{
vals: some Int
}{
#vals = 4
}
one sig s2{
vals: some Int
}{
#vals = 4
}
fact {
all a : s1.vals | a > 2
all i : s2.vals | i < 15
s1.vals = s2.vals
}
pred p{}
run p
It seems to me that {3,4,5,6} at least is a solution however Alloy says no instance found. When I comment s1.vals = s2.vals or change i < 15 to i > 2, it finds instances.
Can anyone please explain me why? Thanks.
Alloy's relationship with integers is sometimes mildly strained; it's not designed for heavily numeric applications, and many uses of integers in conventional programming are better handled in Alloy by other signatures.
The default bit width for integers is 4 bits, and Alloy uses twos-complement integers, so your run p is asking for a world in which integers range in value from -8 to 7. In that world, the constraint i < 15 is subject to integer overflow, and turns out to mean, in effect, i < -1. (To see this, comment out both of your constraints so that you get some instances. Then (a) leaf through the instances produced by the Analylzer and look at the integers that appear in them; you'll see their range is as I describe. Also, (b) open the Evaluator and type the numeral "15"; you'll see that its value in this universe is -1.)
If you change your run command to provide an appropriate bit width for integers (e.g. run p for 5 int), you'll get instances which are probably more like what you were expecting.
An alternative change, however, which leads to a more idiomatic Alloy model, is to abstract away from the specific kind of value by defining a sig for values:
sig value {}
Then change the declaration for vals in s1 and s2 from some Int to some value, and comment out the numeric constraints on them (or substitute some other interesting constraints for them). And then run p in a suitable scope (e.g. run p for 8 value).

Equality in alloy

I've got an Alloy model which contains the following :
abstract sig person{}
one sig john,Steve extends person {Gender: man}
sig man{}
fact {
all name: person, Gender: man |
name.Gender = name.Gender => person =person}
How can I make equality between two signatures?
It's not clear from your question what you want to do, and from your sample Alloy code it looks as if you may be suffering from some confusions.
First, the model you show uses the name Gender in two different ways, which is not illegal in itself but seems to suggest some confusion. (It certainly confuses the willies out of this reader.)
In the declaration for the two singleton signatures john and Steve, Gender denotes two binary relations, one holding between the signature john and the signature man, the other holding between Steve and man. To say the same thing in symbolic form, Gender denotes (a) some subset of john -> man, and (b) some subset of Steve -> man.
In the anonymous fact, however, Gender denotes a variable of type man.
Your model will be easier to understand if you find a way to rename one or the other of these. Since variable names in a quantified expression are arbitrary, your fact will mean the same thing if you reformulate it as
fact { all P : person, M : man | P.M = P.M => person = person }
If that's not what you meant to say, then you may have meant to say something like
fact { all P : person, M : man |
P.Gender = P.Gender => person = person
}
Renaming the variable forces you to choose one meaning or the other. This is a good thing. (It is an unfortunate fact that neither formulation is actually satisfactory in Alloy. But let's deal with one problem at a time; getting rid of the double use of the name Gender is the first step.)
A second issue is that whichever formulation of the fact you meant, it almost certainly doesn't mean what you wanted it to mean. Ignoring the specifics of the model for a moment, your fact takes the form
fact { all V1 : sig1, V2 : sig2 |
Expression = Expression => sig1 = sig1
}
where Expression is either V1.V2 or V1.Relation, for some Relation defined in the model. There are several things wrong here:
V1.V2 is meaningless where V1 and V2 are both names of signatures or variables ranging over given signatures: the dot operator is meaningful only if one of its arguments is the name of a relation.
If any expression E is meaningful at all, then a Boolean expression of the form E = E (for example, person.Gender = person.Gender) is true regardless of what E means. Anything denoted by E is naturally going to be equal to itself. So the conditional might as well be written
1 = 1 => person = person
For the same reason, person = person will always be true, regardless of the model: for any model instance the set of persons in the instance will be identical to the set of persons in the instance. So the conditional will always be true, and the fact won't actually impose any constraint on instances of the model.
It's not clear how best to help you move forward. Perhaps one way to start would be to ask yourself which of the following statements you are trying to capture in your model.
There is a set of persons.
Some persons are males (have gender = 'man'). Others are not males.
John is a male individual.
Steve is a male individual.
John and Steve are distinct individuals.
If x and y are individuals with the same gender, then x and y are the same individual. I.e. no two individuals have the same gender.
Note that these statements cannot all be true at the same time. (If that's not obvious, you might do worse than try to figure out why. Alloy can be helpful in that effort.)
Good luck.

Resources