I have done a little bit of work on Alloy so I understand a fair bit about it. A lot of the shorthand however is not really covered anywhere. What I was wondering was in the example below:
open util/relation
abstract sig Proc { prv : lone (Proc - Remove)
}{
}
fact {acyclic[prv,Proc] // no cycles
}
sig Remove extends Proc{}
sig Begin extends Proc{}{no prv}
sig Action extends Proc{}
pred show() {}
run show for 3
I want to ensure that the final Proc is always going to be a Begin (at the moment it can be a Action too).
There are many ways to write it longhand. I have included one below, which when included ensures that the final Proc (ie one not in a domain) will always be a Begin.
fact {
all p : Proc | p not in dom[prv] implies p in Begin
}
However I like using the shorthand along the lines of (Proc - Remove), for example as makes things so much easier to read, which means that Remove cannot be linked to from another Proc. I hope I have explained that well. I assume there is going to be a really obvious answer but I can't think what it is. Any ideas please?
It sounds as if you could achieve your goal by writing
sig Remove extends Proc{}{some prv}
sig Begin extends Proc{}{no prv}
sig Action extends Proc{}{some prv}
This ensures that no Begin has a prv node, and all non-Begin nodes do.
How about this
fact { ^prv.Begin = Proc - Begin }
It's not super short, but at least it doesn't use a quantifier. I'm not sure if you can do any better than that.
In a graph terminology, it basically says: if you fully expand the prv graph by following all the edges in it as many times as possible (i.e., take transitive closure of prv, ^prv), then select source nodes of those edges that point to a Begin node (^prv.Begin), that set must contain all nodes except the Begin nodes. With the fact you already have which says that Begin nodes have no prv, it implies that starting from any non Begin node and following only the prv links, a Begin node will be reached, and the chain will end there. This fact disallows Action nodes to and such chains.
You can check this claim in Alloy by asserting
check {
// there is no non-Begin node that does not lead to a Begin node
no p: Proc-Begin | no (Begin & p.^prv)
} for 6
and checking that it doesn't find any counterexamples.
Related
I'm writing a grammar for C++ target, however I'd like to keep it working with Java as well since ANTLR comes with great tools that work for grammars with Java target. The book ("The Definitive ANTLR 4 Reference") says that the way of achieving target independence is to use listeners and/or visitors. There is one problem though. Any predicate, local variable, custom constructor, custom token class etc. that I might need introduces target language dependence that cannot be removed, at least according to the information I took from the book. Since the book might be outdated here are the questions:
Is there a way of declaring primitive variables in language independent way, something like:
item[$bool hasAttr]
:
type ( { $hasAttr }? attr | ) ID
;
where $bool would be translated to bool in C++, but to boolean in Java (workaround would be to use int in that case but most likely not in all potential targets)
Is there a way of declaring certain code fragments to be for specific target only, something like:
parser grammar testParser;
options
{
tokenVocab=testLexer;
}
#header
<lang=Cpp>{
#include "utils/helper.h"
}
<lang=Java>{
import test.utils.THelper;
}
#members
<lang=Cpp>{
public:
testParser(antlr4::TokenStream *input, utils::THelper *helper);
private:
utils::THelper *Helper;
public:
}
<lang=Java>{
public testParser(TokenStream input, THelper helper) {
this(input);
Helper = helper;
}
private THelper Helper;
}
start
:
(
<lang=Cpp>{ Helper->OnUnitStart(this); }
<lang=Java>{ Helper.OnUnitStart(this); }
unit
<lang=Cpp>{ _localctx = Helper->OnUnitEnd(this); }
<lang=Java>{ _localctx = Helper.OnUnitEnd(this); }
)*
EOF
;
...
For the time being I'm keeping two separate grammars changing the Java one and merging the changes to C++ one once I'm happy with the results, but if possible
I'd rather keep it in one file.
This target dependency is a real nuisance and I'm thinking for a while already how to get rid of that in a good way. Haven't still found something fully usable.
What you can do is to stay with syntax that both Java and C++ can understand (e.g. write a predicate like a function call: a: { isValid() }? b c; and implement such functions in a base class from which you derive your parser (ANTLR allows to specify such a base class via the grammar option superClass).
The C++ target also got a number of additional named actions which you can use to specify C++ specific stuff only.
I'm working with Microsoft Excel via Delphi 7. It works fine but while formatting rows and ranges I have to write such long strings.
XLApp.Workbooks[1].WorkSheets[NameDoc].Range['A19:L19'].Font.Bold := true;
So I want to get rid of hard work and do it via "with..do" statement like this
with XLApp.Workbooks[1].WorkSheets[NameDoc] do
begin
Range['A19:L19'].Font.Bold := true;
end;
But at compilation stage I see this error
Record, object or class type required
on string - "with..do".
I creating Excel object this way
XLApp: Variant;
XLApp := CreateOleObject('Excel.Application');
I consider that with..do statement doesen't works with variant type variable, but I want to know whether I'm right or not? And if I'm right is there any workaround to make it work?
Variant can be anything or nothing at all - compiler doesn't know it and cannot know: it is so called "dynamically typed value". Since it does not know - it does not know if there would be any members (properties, methods) and if there would - what names would they have.
To get the benefits of strong compile-time typing - including using of with but not only - you have to use interface variables, those that are provided by TExcelApplication component and underlying unit having those values "statically typerd" - thus providing for Delphi compiler to know value types when compiling, in before running. There are plenty of types like iWorsksheet, iRange and others in that unit.
Borland Delphi 7 TExcelApplication.Connect works on office machines but not at client
http://www.delphipages.com/forum/showthread.php?t=157889
http://delphikingdom.ru/asp/viewitem.asp?catalogid=1270
However, since that is about reference-counting and lifetime I'd suggest you go with explicit use of temp variables rather than using with with and implicit invisible variables. Since you cannot control their lifespan and their clearance you might hit the wall in some unexpected place later. I did.
var tmpR: iRange; // assuming we have statically-typed API
// for example - providing we using ExcelXP or Excel2000 unit
tmpR := XLApp.Workbooks[1].WorkSheets[NameDoc];
tmpR.Range['A19:L19'].Font.Bold := true; // instead of with
with tmpR do // also possible but gives little benefit now
begin // when we made a dedicated temp var
Range['A19:L19'].Font.Bold := true;
end;
tmpR := nil; // crucial unless the most short and simplistic functions
// just release hold on Excel's object - let it manage its memory freely,
// by letting Excel know your program no more uses that object.
Also read
https://en.wikipedia.org/wiki/Automatic_Reference_Counting
https://en.wikipedia.org/wiki/Component_Object_Model
Can with be used with a Variant?
No.
You can use with for types whose members are known at compile time. But variants, for which the . operator is evaluated at run time, do not fall into this category. Hence with is not available for variants.
The documentation says, with my emphasis:
A with statement is a shorthand for referencing the fields of a record
or the fields, properties, and methods of an object. The syntax of a
with statement is:
with obj do statement
or:
with obj1, ..., objn do statement
where obj is an expression yielding a reference to a record, object
instance, class instance, interface or class type (metaclass)
instance, and statement is any simple or structured statement.
Sorry if I had this stupid question...I've been trying to google for answer but couldn't find one. :(
I have a problem assigning a variable to a virtual interface. For example:
Param.sv
...
string MyInput[3];
MyInput[0] = Signal_CLK; //Storing SignalName to in an Array.
MyInput[1] = Signal_Tx;
MyInput[2] = Signal_Rx;
...
MyInterface.sv
...
Signal_CLK = dut.MicroController.Source.clk; //Signal destination
Signal_Tx = dut.MicroController.Tx_01;
Signal_Rx = dut.MicroController.Rx_01;
...
Test.sv
virtual MyInterface my_vif
logic [7:0] read_value;
....
for (i = 0; i <3; i++ )
begin
read_value = my_vif.My_Input[i];
..
//some logic to compare read_value with spec//
..
end
The problem is when compiling, it doesn't translate my_vif.My_Input[0] into my_vif.***dut.MicroController.Source.clk***. Instead, it thinks that the path is my_vif.***My_Input[i]***.
The reason the compiler thinks you are trying to access my_vif.My_Input[i] is because you are. The My_Input[] array is a completely separate string array; not part of the virtual interface. When using the "thing.thing.thing" syntax, the compiler will loyally follow it, so it will expect there to be something called My_Input that has some elements (as its an array) as a member of the interface given by my_vif.
However, looking over youre code, you are trying to have My_Input[i] replaced at compile time, which is very different. The compiler will not run your loop, look in My_Input[i] and find the string "Signal_CLK" and replace that as part of the path to get the path my_vif.Signal_CLK. Nor can it do that at run time.
I dont know of a generic solution to looking over any variables in an interface; though Im also not sure if thats really what you want. IF you provide more details on the rest of your checker, we might be able to help you more.
You cannot use strings to look up identifiers by name within SystemVerilog. There are tool specific and C interfaces that may let you do this, but that would be very inefficient. The best way to do this by using a combination of abstract/concrete classes and the bind construct. See these references: http://events.dvcon.org/2012/proceedings/papers/01P_3.pdf and http://www.doulos.com/knowhow/sysverilog/DVCon08/DVCon08_SysVlog.php
I'm trying to debug behaviour that has only appeared when my large app - working fine in XE3 - is run after compiling with XE4. The issue seems to cause some quoted strings (eg "MyString") to retain their quotes even after having been 'de-quoted' by TPageProducer in Web.HTTPProd. For example, consider the code below which is small extract from this Delphi source unit Web.HTTPApp:
procedure ExtractHeaderFields(Separators, _WhiteSpace: TSysCharSet; Content: PChar;
Strings: TStrings; Decode: Boolean; StripQuotes: Boolean = False);
{$ENDIF NEXTGEN}
var
Head, Tail: PChar;
EOS, InQuote, LeadQuote: Boolean;
QuoteChar: Char;
ExtractedField: string;
{$IFNDEF NEXTGEN}
WhiteSpaceWithCRLF: TSysCharSet;
SeparatorsWithCRLF: TSysCharSet;
{$ENDIF !NEXTGEN}
function DoStripQuotes(const S: string): string;
var
I: Integer;
InStripQuote: Boolean;
StripQuoteChar: Char;
begin
Result := S;
InStripQuote := False;
StripQuoteChar := #0;
if StripQuotes then
begin
for I := Result.Length - 1 downto 0 do
if Result.Chars[I].IsInArray(['''', '"']) then
if InStripQuote and (StripQuoteChar = Result.Chars[I]) then
begin
Result.Remove(I, 1);
InStripQuote := False;
end
else if not InStripQuote then
begin
StripQuoteChar := Result.Chars[I];
InStripQuote := True;
Result.Remove(I, 1);
end
end;
end;
I see this called when I use TPageProducer and I can see my good source string go into the ExtractHeaderFields routine above and then into the 'DoStripQuotes' function. Stepping into DoStripQuotes and watching 'Result' shows that it does not change, even when Result.Remove is called (to strip the quote). When I take this 'DoStripQuotes' routine out to a simple test app, it wont compile, telling me that 'Result.anything' is not allowed. I assume then that Result, although it is defined as 'string' must be another type of string in the context of Web.HTTPProd.
So I get to thinking maybe this is something to do with the 'Immutable strings' that I've heard about. I read this SO question about that and although I get the gist, I could do with more practical advice.
Specifically, I would like answers to the following questions:
What type of 'string' is 'Result' if the notation Result.Length is allowed?
Is there a way in which I can tell the compiler to use 'XE3' compatibility for a unit? (THis might allow me to see where the problem is originiating). Ive ttried {$ZEROBASEDSTRINGS ON} / OFF but this seems to cause even more chaos and I don't know what I'm doing!
Thanks for any help.
LATER EDIT: As noted in the accepted answer below this is a bug in the VCL unit Web.HTTPApp.pas which should read "Result := Result.Remove(I,1)" in two places around line 2645 and not "Result.Remove(I,1)"
What type of 'string' is 'Result' if the notation Result.Length is allowed?
It's just the same old string, aliased to UnicodeString, that you've been using since Delphi 2009. The difference is that this code uses the new record helper (specifically SysUtils.TStringHelper). That's what lets you use . notation on a string variable.
Is there a way in which I can tell the compiler to use 'XE3' compatibility for a unit?
No. The code in question is a library unit and it is designed to be compiled in a particular mode. What's more, you can't readily re-compile it unless you take on compiling the RTL/VCL yourself. Even if there was such a mode, it would not help since the code is simply wrong (see below). No amount of mode switching can fix this particular piece of code.
I get to thinking maybe this is something to do with the Immutable strings that I've heard about.
It's not. None of the Delphi compilers have immutable strings yet. The concept of immutable strings is just something that has been floated as a future change. And if the change is made, expect it to be made in the mobile compilers first.
The problem is in fact just a rather simple bug in the code that you posted which has clearly had no testing at all. The use of Remove is wrong. That method does not modify the string in-place. Instead it returns a new string that has the character removed. The code should read:
Result := Result.Remove(I, 1);
The reason that the developer who coded ExtractHeaderFields has made this mistake is that whoever designed the string helper code named the Remove method incorrectly. Since Remove is a verb you would expect it to operate in-place. A method that does not modify the subject, and returns a new instance, as this method does, should be given a name that is a noun. So this method should be named something like Remnants. It looks to me as though the RTL designers copied the .net naming where the same flaw also exists.
You should submit a QC report, if one does not already exist. I know that XE4 update 1 has just been released. It's plausible that it contains a fix.
Your other options, as I see them, are:
Stick with XE3 until XE4 is sufficiently debugged.
Include a copy of the Web.HTTPApp unit in your project and fix the bugs yourself.
The following (rightfully) doesn't work:
package main
import (
"os"
"time"
)
func main() {
os.Args[0] = "custom name"
println("sleeping")
time.Sleep(1000 * time.Second)
println("done")
}
Some languages provide this feature of setting process name as a built-in functionality (in Ruby, for instance, it is only a matter of assigning to $0) or as a third-party library (Python).
I'm looking for a solution that works, at least, on Linux.
There are multiple ways to accomplish this, and many of them only work in certain situations. I don't really recommend doing it, as (for one thing) it can result in your process showing up with different names in different situations. They require using syscall and/or unsafe, and so you're deliberately subverting the safety of the Go language. That said, however, your options seem to be:
Modify argv[0]
func SetProcessName(name string) error {
argv0str := (*reflect.StringHeader)(unsafe.Pointer(&os.Args[0]))
argv0 := (*[1 << 30]byte)(unsafe.Pointer(argv0str.Data))[:argv0str.Len]
n := copy(argv0, name)
if n < len(argv0) {
argv0[n] = 0
}
return nil
}
In Go, you don't have access to the actual argv array itself (without calling internal runtime functions), so you are limited to a new name no longer than the length of the current process name.
This seems to mostly work on both Darwin and Linux.
Call PR_SET_NAME
func SetProcessName(name string) error {
bytes := append([]byte(name), 0)
ptr := unsafe.Pointer(&bytes[0])
if _, _, errno := syscall.RawSyscall6(syscall.SYS_PRCTL, syscall.PR_SET_NAME, uintptr(ptr), 0, 0, 0, 0); errno != 0 {
return syscall.Errno(errno)
}
return nil
}
The new name can be at most 16 bytes.
This doesn't work on Darwin, and doesn't seem to do much on Linux, though it succeeds and PR_GET_NAME reports the correct name afterward. This may be something peculiar about my Linux VM, though.
To change a process name on Linux, you need to use the prctl system call combined with the PR_SET_NAME option.
At the moment, I don't think you can do this in Go code. You can, however, build a small C module to do this and then integrate it into your Go build.
I don't think that "process title" is a well defined term. Anyway, what has Ruby to do with Go? The documentation for os.Args doesn't mention any "process title", nor it says any magic will happen on assigning to a slice item. The later is actually a general property of Go. There's no magic getters/setters for struct fields, variables of array/slice items, so a simple assignment simply assigns and does nothing more and cannot do anything more.
In short, the lack of magic is the expected, correct behavior.
For fiddling with process properties other than the portably accessible ones via the 'os' package, one has to use package 'syscall' in a platform specific way. But then the build constraints (discussed here) can help to correctly handle stuff across platforms.