Search code examples
alloy

Alloy pred declaration: is there a difference between square brackets and parentheses?


The question probably has a yes/no answer. Consider the snippet:

sig A { my : lone B }
sig B { }

pred single1 [x:A]{ // defined using []
    #x.my = 0
}
pred single2 (x:A){ // defined using ()
    #x.my = 0
}

// these two runs produce the exact same results
run single1 for 3 but exactly 1 A
run single2 for 3 but exactly 1 A

check oneOfTheMostTrivialQuestionsOnStackOverflow { all x: A | 
    single1[x] iff single2[x] // pred calls use [], so as expected, single2(x) would cause a syntax error
} for 3000 but exactly 1 A // assertion holds :)

Are single1 and single2 exactly the same?

They seem to be, but am I missing something?


Solution

  • When we extended the syntax in Alloy 4, we changed the predicate invocations to []. My recollection is that we did it to make parsing easier, so that if you had a predicate P with no args, you could call it as just "P", and there would be no problems if it were followed by a formula in parens "P (...)". As Peter notes, it also seemed reasonable since it's similar to the relational lookup operator, and this makes sense especially for functions. We added the ability to declare predicates and functions with [] for consistency, but saw no reason to prevent () in decls (since there's no possible ambiguity there).