I'd like to have a Maxima function to detect functions that have already been defined. This could be called is_function, so that is_function(sin) and is_function(exp) would be true, but is_function(%pi) and is_function(foo) would be false (assuming that I have not defined foo). Does this exist already?
The manual says
Some Lisp functions are shadowed in the Maxima package, namely the following ... functionp ...
I'm not sure exactly what this means, but functionp(sin) returns false, and functionp(foo) also returns false even if I define foo(x) := x;. Also, fundef(sin) and dispfun(sin) fail with message fundef: no such function: sin, although fundef(foo) works if I define foo(x) as before.
There are several ways to define functions, and Maxima doesn't really have a way to detect any of them.
UPDATE: An slightly expanded version of the previous solution can now be found at: https://github.com/maxima-project-on-github/maxima-packages in the folder robert-dodier/fboundp.
PREVIOUS SOLUTION: Here's an attempt which looks at the Lisp symbol properties to see what's there.
/* fboundp.mac -- detect different kinds of functions in Maxima
* copyright 2020 by Robert Dodier
* I release this work under terms of the GNU General Public License
*
* Examples:
*
/* Simplifying function defined in Lisp: */
fboundp(sin);
true;
fboundp_simplifying(sin);
true;
/* DEFUN (ordinary argument-evaluating) function defined in Lisp: */
fboundp(expand);
true;
fboundp_ordinary_lisp(expand);
true;
/* DEFMSPEC (argument-quoting) function defined in Lisp: */
fboundp(kill);
true;
fboundp_quoting(kill);
true;
/* Maxima ordinary function: */
(kill(foo),
foo(x) := x,
fboundp(foo));
true;
fboundp_ordinary_maxima(foo);
true;
/* Maxima array function: */
(kill(bar),
bar[x](y) := x*y,
fboundp(bar));
true;
fboundp_array_function(bar);
true;
/* Maxima macro: */
(kill(baz),
baz(x) ::= buildq([x], x),
fboundp(baz));
true;
fboundp_maxima_macro(baz);
true;
*
*/
fboundp(a) :=
fboundp_simplifying(a)
or fboundp_ordinary_lisp(a)
or fboundp_quoting(a)
or fboundp_ordinary_maxima(a)
or fboundp_array_function(a)
or fboundp_maxima_macro(a);
fboundp_simplifying(a) :=
symbolp(a) and ?get(a, ?operators) # false;
fboundp_ordinary_lisp(a) :=
symbolp(a) and ?fboundp(a) # false;
fboundp_quoting(a) :=
symbolp(a) and ?get(a, ?mfexpr\*) # false;
fboundp_ordinary_maxima(a) :=
symbolp(a) and ?mget(a, ?mexpr) # false;
fboundp_array_function(a) :=
symbolp(a) and ?mget(a, ?aexpr) # false;
fboundp_maxima_macro(a) :=
symbolp(a) and ?mget(a, ?mmacro) # false;
EDIT: I've made a separate function to test for each kind of function, and I put in a test for symbolp to ensure that the property-inspection stuff (?get and ?mget) won't fail.
Related
I'm new to Dafny. I'm getting the error: call might violate context's modifies clause on the line where Seek() calls Step() in the following code:
class Tape {
var val : int;
constructor() {
this.val := 0;
}
method Write(x : int)
modifies this
{
this.val := x;
}
}
class Simulator {
var tape : Tape;
var step_num : nat;
constructor() {
this.tape := new Tape();
this.step_num := 0;
}
method Step()
modifies this, this.tape
ensures this.step_num > old(this.step_num)
{
this.tape.Write(1);
this.step_num := this.step_num + 1;
}
method Seek(target_step_num : int)
modifies this, this.tape
{
while this.step_num < target_step_num {
this.Step();
}
}
}
I don't understand what's going on here because I explicitly annotated Seek() with modifies this, this.tape.
Looking around online I see some talk about "freshness" and I get the impression that this has to do with ensuring that I have permission to access this.tape, but I don't understand how to fix it. Thanks!
You need invariant that this.tape is not reassigned to something else in methods. Adding ensures this.tape == old(this.tape) post condition in Seek and Step and also adding invariant this.tape == old(this.tape) fixes it.
FWIW, in addition to Divyanshu's excellent answer, I also discovered that I could fix this issue by defining tape as a const:
class Simulator {
const tape : Tape;
var step_num : nat;
...
In this case, it appears that const means that the pointer/reference will never be modified (that it will never point to a different Tape object), not that the Tape object itself will be unmodified.
Looking for help on how to cast / convert a pointer to a record - similar to what dotNet's Marshal.PtrToStructure does - but using Delphi.
Details: using an ActiveX / COM (original code in C++). Implementing an interface allowing to catch events raised by the ActveX control.
One of the implemented interface's methods signature looks like:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
IUIX_Event is an interface (derives from IDispatch). Has a property Param1 of type Param_T.
Param1 holds a pointer to a record type.
Now, I have C# code I would like to convert to Delphi:
public void OnEvent(IUIX_Obj pSender, IUIX_Event pEvent)
{
//some more code before, and then this part:
IntPtr outPtr = new IntPtr(pEvent.Param1);
UIX_NotifyInfo ni = (UIX_NotifyInfo)System.Runtime.InteropServices.Marshal.PtrToStructure(outPtr, typeof(UIX_NotifyInfo));
}
UIX_NotifyInfo is a record (/struct).
Qustion: how to go from pEvent.Param1 to ni? Using Delphi:
procedure TIUIX_ObjImplEvent.OnEvent(const pSender: IUIX_Obj; const pEvent: IUIX_Event);
var
ni : UIX_NotifyInfo;
begin
pEvent.Handled := false;
if (pEvent.Code = e_Notify) then
begin
//how to go from pEvent.Param1 to ni like in C#'s PtrToStructure?
if (ni.nCode = UIX_Notify_BeforeShowPopup) then
begin
pEvent.Handled := true;
end;
end;
end;
My guess is using the Move procedure, but whatever I try it either does not compile or crashes :)
Move(??, ni, SizeOf(UIX_NotifyInfo));
I'm adding this after David answered...
Here's an extension to the above question (looking for how to go about Marshal.GetObjectForIUnknown).
I have this C# code:
public void OnEventMonitor(IUIX_Obj pTarget, IUIX_Event pEvent)
{
IntPtr outPtr;
pTarget.QueryImpl(typeof(IUIX_Dialog).GUID, null, out outPtr);
IUIX_Dialog dlg = (IUIX_Dialog)System.Runtime.InteropServices.Marshal.GetObjectForIUnknown(outPtr);
}
Having:
IUIX_Event = interface(IDispatch)
IUIX_Obj = interface(IDispatch)
IUIX_Dialog = interface(IUIX_ObjImpl) (IDispatch)
My Delphi code (dlg : IUIX_Dialog, pImpl : Pointer):
pTarget.QueryImpl(GetTypeData(TypeInfo(IUIX_Dialog)).Guid, nil, #pImpl);
Move(pImpl, dlg, SizeOf(IUIX_Dialog));
The above does work.
Any better approach or that's correct way?
It's simple in unmanaged code, it's just an assignment.
var
Rec: TMyRec;
Ptr: Pointer;
....
Rec := TMyRec(Ptr^);
I downloaded the VirtualTreeView component for Borland C ++ Builder 6.0 and I'm trying to learn how to use it. Unfortunately I can not find any code for this compiler that serves as an example and I am based on a Delphi code that I have given.
I have created a project with a single form that contains only one TVirtualStringTree. I am using this code to try to understand how it works.
In the CPP:
void __fastcall TForm1 :: FormCreate (TObject * Sender)
{
AnsiString cLiteral;
PTrecBase pRecData;
PVirtualNode Node;
VST-> BeginUpdate ();
VST-> Clear ();
VST-> NodeDataSize = sizeof (TRecBase);
for (int nItem = 0; nItem <10; nItem ++)
{
cLiteral = "Node" + IntToStr (nItem);
Node = VST-> AddChild (NULL);
pRecData = (PTrecBase) VST-> GetNodeData (Node);
pRecData-> Literal = cLiteral;
for (int nSub = 0; nSub <5; nSub ++)
{
Node = getNodeDondeInsert (cLiteral);
Node = VST-> AddChild (Node);
pRecData = (PTrecBase) VST-> GetNodeData (Node);
pRecData-> Literal = cLiteral + "Sub" + IntToStr (nSub);
}
}
VST-> EndUpdate ();
}
In the H:
class TForm1: public TForm
{
__published: // IDE-managed Components
TVirtualStringTree * VST;
void __fastcall FormCreate (TObject * Sender);
private: // User declarations
public: // User declarations
__fastcall TForm1 (TComponent * Owner);
};
struct TRecBase
{
AnsiString Literal;
};
typedef TRecBase * PTrecBase;
However I can not get the literal that I want to show. Only this is shown:
And I do not know what I'm doing wrong so that you do not see the literals that I'm defining. Does anyone have a code for C ++ Builder that can guide me? Thank you.
You are storing string data for each node, but you have no event handlers assigned to the TreeView, particularly OnGetText, to supply those strings to the TreeView when it is being rendered. This is a virtual control, you have to supply it with data when it asks you for it.
There is a C++Builder demo available on VirtualTreeView's GitHub repository
Thanks for your reply.
The code that you have indicated to me I have already tried it and I am not able to understand it because I can not find in which part of it it is necessary to indicate the literal of the node. The attached image is the result I get with that example code.
Form CBMininal
As you can see the result is practically the same as in the image that I went up yesterday. What I'm most sorry about is that even though I searched, I did not find any sample code for this component for Borland C ++.
What's more: If I run the example with the debugger, the same thing happens to me as with my code.
In my code when I execute the line pRecData->Literal = cLiteral; I can see in the debugger that it has the calculated values (Node 0, Node 1, etc.) and in the example, when this one is executed (Text = Data->Caption;) I can see that both Text and Data->Caption contain the value, for example, Level 0, Index 5 but this literal is not shown in the TVirtualStringTree.
I am using a biometrics SDK. And I converted the headers to delphi to consume the dll.
It looks something like this:
const
{VrBio_EventType}
VRBIO_CAPTURE_EVENT_UNPLUG = $001; {Fingerprint scanner unplugged from the computer.}
VRBIO_CAPTURE_EVENT_PLUG = $002; {Fingerprint scanner plugged on the computer.}
VRBIO_CAPTURE_EVENT_REMOVED = $004; {Finger removed from the fingerprint scanner.}
VRBIO_CAPTURE_EVENT_PLACED = $008; {Finger placed on the fingerprint scanner.}
VRBIO_CAPTURE_EVENT_IMAGE_FRAME = $10; {A fingerprint frame was captured on the fingerprint scanner.}
VRBIO_CAPTURE_EVENT_IMAGE_CAPTURED = $020; {A fingerprint image was captured on the fingerprint scanner.}
VRBIO_CAPTURE_EVENT_FAKE_FINGER_DETECTED = $400; {A false finger has been detected on the sensor}
VRBIO_CAPTURE_EVENT_FAKE_FINGER_REMOVED = $800; {A false finger has been removed from the sensor}
type
(* Stores the parameters of the ISO 19794-4 image format. #see VGetReaderProperties #see VrBio_ReaderProperty
typedef struct
{
/** #see VrBio_ISO197944CompressionMode*/
int compressionMode;
/** #see VrBio_ISO197944ImpressionType*/
int impressionType;
/** #see VrBio_ISO197944FingerPosition*/
int fingerPosition;
}VrBio_ISO197944Parameters;
*)
PISO197944Parameters = ^TISO197944Parameters;
TISO197944Parameters = record
compressionMode: Integer; { #see VrBio_ISO197944CompressionMode}
impressionType: Integer; { #see VrBio_ISO197944ImpressionType}
fingerPosition: Integer; { #see VrBio_ISO197944FingerPosition}
end;
(* Represents a biometric image. #see VrBio_CaptureEventCallback \ref VSyncCapture
struct VrBio_BiometricImage
{
/** Image width.*/
int width;
/**Image height*/
int height;
/**Image resolution in dpi. For the obsolete functions, use pixels/cm.*/
int resolution;
/**Number of channels in the image. Fingerprint images should always be grayscale, so this value is always 1.*/
int channels;
/**Biometric modality.
* Always use VRBIO_BIOMETRIC_MODALITY_FINGERPRINT.
* \ref VrBio_BiometricModality.
*/
int biometricModality;
/**Scanner type.
* \ref VrBio_ScannerType.
*/
int scannerType;
/**Formato de imagem: Formato da imagem.
*\ ref VrBio_ImageFormat.*/
int imageFormat;
/**Size of the buffer*/
int bufferSize;
/**Compression rate. Valid for images that allow compression.
* \ref VrBio_CompressionRate
*/
int compressionRate;
/**Quality of the fingerprint image.
* \ref VrBio_FingerQuality
*/
int fingerQuality;
/** Only valid if the image if imageFormat is \ref VrBio_ImageFormat::VRBIO_IMAGEFORMAT_ISO19794_4
*\ref VrBio_ISO197944Parameters
*/
VrBio_ISO197944Parameters* ISO197944_parameters;
/** Buffer storing the pixels of the image.
The position(x,y,c) of a pixel is y*width*channels+x*channels+c.
*/
unsigned char* buffer;
/**Reserved for future use*/
void* reserved;
};
typedef struct VrBio_BiometricImage VrBio_BiometricImage;
*)
PBiometricImage = ^TBiometricImage;
TBiometricImage = record
width: Integer; { Image width. }
height: Integer; { Image height }
resolution: Integer; { Image resolution in dpi. For the obsolete functions, use pixels/cm.}
channels: Integer; { Number of channels in the image. Fingerprint images should always be grayscale, so this value is always 1. }
biometricModality: Integer; { Biometric modality. Always use VRBIO_BIOMETRIC_MODALITY_FINGERPRINT. \ref VrBio_BiometricModality. }
scannerType: Integer; { Scanner type. \ref VrBio_ScannerType. }
imageFormat: Integer; { Formato de imagem: Formato da imagem. \ ref VrBio_ImageFormat. }
bufferSize: Integer; { Size of the buffer }
compressionRate: Integer; { Compression rate. Valid for images that allow compression. \ref VrBio_CompressionRate }
fingerQuality: Integer; { Quality of the fingerprint image. \ref VrBio_FingerQuality }
ISO197944_parameters: PISO197944Parameters; { Only valid if the image if imageFormat is \ref VrBio_ImageFormat::VRBIO_IMAGEFORMAT_ISO19794_4 \ref VrBio_ISO197944Parameters }
buffer: PByte; { Buffer storing the pixels of the image. The position(x,y,c) of a pixel is y*width*channels+x*channels+c. }
reserved: Pointer; { Reserved for future use }
end;
(*
#include "VTypes.h"
#ifdef WIN32
#define DLLIMPORT extern "C" __declspec(dllimport) int __stdcall
#else
#define DLLIMPORT extern "C"
#endif
*)
{ Callback function that receives events..
typedef void (*VrBio_CaptureEventCallback) (
int eventType,
const char* readerName,
VrBio_BiometricImage* image,
const void* userData)
}
TCaptureEventCallback = procedure(eventType: Integer; readerName: PAnsiChar; image: PBiometricImage; userData: Pointer); stdcall;
{ Function responsible for initializing the SDK. This function MUST be called before calling any other method, except \ref VInstallLicense
DLLIMPORT VStartSDK(VrBio_CaptureEventCallback eventCallback);
}
function VStartSDK(eventCallback: TCaptureEventCallback): Integer; stdcall;
{ Function responsible for finalizing the SDK. This function should be called when the SDK is not needed in the application anymore.
DLLIMPORT VStopSDK();
}
function VStopSDK(): Integer; stdcall;
{ Function responsible for starting the capture on a specific fingerprint reader.
After calling this function, the application is able to receive events.
DLLIMPORT VStartReader(const char* readerName);
}
function VStartReader(readerName: PAnsiChar): Integer; stdcall;
Using it looks like this:
implementation
{$R *.dfm}
procedure EventCallback(eventType: Integer; readerName: PAnsiChar; image: PBiometricImage; userData: Pointer); stdcall;
begin
case eventType of
VRBIO_CAPTURE_EVENT_UNPLUG: Form1.Memo1.Lines.Add('Leitor desconectado!');
VRBIO_CAPTURE_EVENT_REMOVED: Form1.Memo1.Lines.Add('Dedo removido!');
VRBIO_CAPTURE_EVENT_PLACED: Form1.Memo1.Lines.Add('Dedo detectado!');
VRBIO_CAPTURE_EVENT_IMAGE_FRAME: Form1.Memo1.Lines.Add('Frame capturado!');
VRBIO_CAPTURE_EVENT_IMAGE_CAPTURED: Form1.Memo1.Lines.Add('Imagem capturada!');
VRBIO_CAPTURE_EVENT_FAKE_FINGER_DETECTED: Form1.Memo1.Lines.Add('Dedo falso detectado!');
VRBIO_CAPTURE_EVENT_FAKE_FINGER_REMOVED: Form1.Memo1.Lines.Add('Dedo falso removido!');
VRBIO_CAPTURE_EVENT_PLUG:
begin
VStartReader(readerName);
Form1.Memo1.Lines.Add('Leitor conectado!');
end;
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
VStartSDK(EventCallback);
end;
My questions:
I can use the application and get the Plug, Unplug and Placed events, but when I get the Image Captured event I have an acces vilation.
In the events that are working the EventCallback parameter image is nil. Is the TBiometricImage record conversion correct?
How can I convert the TBiometricImage buffer to a TBitmap and display the captured image in a TImage?
when I get the Image Captured event I have an acces vilation. In the events that are working the EventCallback parameter image is nil. Is the TBiometricImage record conversion correct?
The individual fields are declared fine, but double check that the alignment and padding of your Delphi records match the same alignment and padding used by the structs in C/C++.
Also, more importantly, the VrBio_CaptureEventCallback typedef in C/C++ is declared without any calling convention specified, so it will use the compiler's default convention, which is usually __cdecl instead of __stdcall (can be configured in the compiler settings). In Delphi, you declared TCaptureEventCallback to use stdcall instead of cdecl. You have to make sure you match the calling conventions correctly (the exported DLL functions do use stdcall, so you are OK there).
How can I convert the TBiometricImage buffer to a TBitmap and display the captured image in a TImage?
The SDK documentation does not explain how to process the various image formats. However, just looking at the struct declaration, the buffer field points at the actual image data, and the imageFormat field indicates the format of that data (there is a VrBio_ImageFormat enum that you have not translated yet). So, you would have to look at the imageFormat first to know how to interpret the buffer.
I do see a VConvertImage() function available. So you should be able to convert images to BMP format, if they are not already. Based on the samples in the SDK, it looks like the buffer data might be a standard BMP file format, so you could try copying the buffer to a TMemoryStream and then use the TBitmap.LoadFromStream() method.
There are also GIF and JPG image formats available, which could be handled by TGIFImage and TJPEGImage, respectively, or even TWICImage, if you wanted to display scanned GIF/JPG images without having to convert them to BMP first. There is also a RAW image format available (which apparently your images are using), but there is no standard VCL TGraphic class to handle RAW images, but I think there might be some 3rd party classes floating around if you look around.
Otherwise, you might try converting the image data to BMP, if needed, and then pass the buffer to the Win32 API CreateBitmap/Indirect() or CreateDibSection() function, and then assign the resulting HBITMAP to the TBitmap.Handle property if successful.
What is the point of lua_lock and lua_unlock?
The following implies it's important:
LUA_API void lua_gettable (lua_State *L, int idx) {
StkId t;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
luaV_gettable(L, t, L->top - 1, L->top - 1);
lua_unlock(L);
}
LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
StkId t;
TValue key;
lua_lock(L);
t = index2adr(L, idx);
api_checkvalidindex(L, t);
setsvalue(L, &key, luaS_new(L, k));
luaV_gettable(L, t, &key, L->top);
api_incr_top(L);
lua_unlock(L);
}
The following implies it does nothing:
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
Please enlighten.
If you port Lua to another platform, you are "allowed" to overwrite lua_lock with your own definition; and this definition should essentially be a mutex, to disallow cross-thread operations on the same Lua objects. Essentially, when implemented, it should act similarly to Python's Global Interpreter Lock (GIL).
It's defined to a no-op in vanilla Lua, because vanilla Lua is 100% ANSI-C and runs in a single thread: there's no need for any locking mechanism to be implemented. However, the developers chose to put the lock statements in there for people who port Lua and implement threading in the interpreter.
Sources:
Proposal: fast lua_lock
Why write lua_unlock before lua_lock?
Mailing list