Mercury "undefined reference" compilation error when using local module - mercury

I have a module exporting nat/1 to test/generate natural numbers:
:- module nat.
:- interface.
:- import_module int.
:- pred nat(int).
:- mode nat(in) is det.
:- mode nat(out) is multi.
:- implementation.
:- pragma promise_pure(nat/1).
nat(_::in).
nat(0::out).
nat(X::out) :- nat(Y), X = Y + 1.
and a main module in the same directory to try it out:
:- module main.
:- interface.
:- import_module io.
:- pred main(io__state::di, io__state::uo) is cc_multi.
:- implementation.
:- import_module nat.
main(!IO) :- nat(X), print(X, !IO).
I run mmc --make-int nat.m which successfully generates the interface files, but then when I run mmc main.m I get the following error:
/usr/bin/ld: main.o: in function `<predicate 'main'/2 mode 0>':
main.c:(.text+0x45): undefined reference to `<predicate 'nat.nat'/1 mode 1>'
collect2: error: ld returned 1 exit status
I'm using MMC version 20.06.1, on x86_64-pc-linux-gnu.
Am I missing something obvious? Code improvements are also very welcome.

After "mmc --make-int nat.m", the command you need to run is not "mmc main.m",
but "mmc main.m nat.m". The former compiles only main.m, while the latter also compiles nat.m. Both attempt to build an executable from the resulting
object files, but the former will fail, since the definition of the "nat" predicate would be in the object file it does not generate.
In general, instead of trying to manage the creation of interface files, object files and executables manually, it is much easier to use an automated
build system: either the mmake script, or mmc --make.
As for code improvements, I would suggest replacing io__state with just plain io, which is a lot shorter. We added "io" as a synonym for the "state"
type in io.m specifically to make this possible.

Related

nim: Use a static library

I've tried to get an audio library statically linked to my program. I use this nimble package. To get it run, i had to build the soloud library as described here. For short after download i ran "genie --with-miniaudio-only --platform=x64 vs2017" in the "build" folder and got the source code to generate the dynamic and the static library. For now i can run the following demo program from the nimble package with the generated dll alongside:
import solouddotnim, times, os
var i, spin = 0
var sl : ptr Soloud
sl = Soloud_create()
discard Soloud_init(sl)
Soloud_setGlobalVolume(sl, 1)
var stream = WavStream_create()
discard WavStream_load(cast[ptr Wav](stream), "test.ogg")
let currentTime = epochTime()
let length = WavStream_getLength(stream)
discard Soloud_play(cast[ptr Soloud](sl), cast[ptr Wav](stream))
while epochTime() - currentTime <= length:
sleep(100)
Soloud_deinit(sl)
Soloud_destroy(sl)
Now to the static-link part. In the solouddotnim.nim file of the nimble package i use, i see this part:
when defined(windows):
const
libname* = "libsoloud.dll"
elif ...
So i simple changed the windows part to the following, re-installed the nimble-package and placed the "soloud_static_x64.lib" alongside to the "main.nim" of the testproject:
when defined(windows):
const
libname* = "soloud_static_x64.lib"
elif ...
But this doesent make it. (cant open "soloud_static_x64.lib" error when build)
Evereywhere where the constant "libname" is used there are the pragmas "cdecl", "importc" and "dynlib". For example:
proc Soloud_create*(): ptr Soloud {.cdecl, importc: "Soloud_create", dynlib: libname.}
So "dynlib" is telling nim to use a dll on windows. But was is the pragma for static libraries?
In the nim documentations i only found DynlibOverride to link to static libraries, but i dont understand the example and here is where i stuck. I've tried the followings:
nim c --dynlibOverride:libname --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
nim c --dynlibOverride:soloudtotnim --passL:soloud_static_x64.lib "examples\00-ogg\Example00_ogg.nim"
Firstly i dont know what parameter dynlibOverride expects and secondly both compiles, but dont work. It expects a dynamic library alongside the exe.
My last try was to remove all dynlib pragmas from the nimble package. But now i cant compile it.
undefined reference to `Soloud_create'
...
Error: execution of an external program failed: 'gcc.exe...
My knowlege ends here. Can someone help me?
Thanks in advance.
Edit:
I could not get any of your solutions work. I break down the problem as small as possible so everybody can reproduce this:
"foo.nim" contains this:
proc add*(a, b: int): int {.cdecl, exportc.} =
a + b
proc sub*(a, b: int): int {.cdecl, exportc.} =
a - b
The .lib is simply generated with this command: "nim c --app:staticlib foo.nim"
Now to use it i created a file "main.nim" with this content:
{.passL:"foo.lib".}
proc add*(a, b: int):int {.cdecl, importc.}
proc sub*(a, b: int):int {.cdecl, importc.}
echo add(10, 5)
echo sub(10, 5)
if i simply build it with "nim c -r main.nim", i get the following output and error:
P:\Nim\LearnCBinding>nim c -r main.nim
Hint: used config file 'C:\nim-1.5.1\config\nim.cfg' [Conf]
Hint: used config file 'C:\nim-1.5.1\config\config.nims' [Conf]
....CC: stdlib_io.nim
CC: stdlib_system.nim
CC: main.nim
Hint: [Link]
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x1f6): multiple definition of `PreMainInner'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x120): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x20a): multiple definition of `PreMain'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x134): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x240): multiple definition of `NimMainInner'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x16f): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x254): multiple definition of `NimMain'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x183): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x285): multiple definition of `main'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x1b4): first defined here
foo.lib(#mfoo.nim.c.o):#mfoo.nim.c:(.text+0x2da): multiple definition of `NimMainModule'
C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o:#mmain.nim.c:(.text+0x209): first defined here
collect2.exe: error: ld returned 1 exit status
Error: execution of an external program failed: 'C:\nim-1.5.1\dist\mingw64\bin\gcc.exe -o P:\Nim\LearnCBinding\main.exe C:\Users\Peter\nimcache\main_d\stdlib_io.nim.c.o C:\Users\Peter\nimcache\main_d\stdlib_system.nim.c.o C:\Users\Peter\nimcache\main_d\#mmain.nim.c.o foo.lib '
Because of the multiple definition error i also tried to build foo.lib with parameter "--noMain:on", but it doesnt make any difference.
Do you have the same problem? By the way i use the current version of Nim "nim-1.5.1" and reinstalled MingW with the finish.exe from nim.
I will try to help you with the following error you have:
undefined reference to `Soloud_create'
but i will assume that you have configured your environment so you can compile your nim programs with visual studio compiler (by adding --cc:vcc to your compile command)
this is because you already seem to have visual studio 2017 and you are compiling soloud static library with it. I think this is the best option when you are compiling with one compiler both: static library and executable that will use it.
open your static library (soloud_static_x64.lib) with some text/hex editor and search for "Soloud_create". i guess you will not find anything. so why is that? because for some reason author decided to not include "C interfacing" in a static library project. so it contains only C++ symbols and not pure C symbols that are needed for our solouddotnim.nim module.
let's try to find out what .cpp file we need for that. i noticed this information on official web site of Soloud - http://sol.gfxile.net/soloud/c_api.html
so i guess we need only one file: soloud_c.cpp
let's try to just include it in SoloudStatic.vcxproj file generated by you with Genie. like this:
..
<ClCompile Include="..\..\src\c_api\soloud_c.cpp">
</ClCompile>
..
and recompile our static library. i use this command in powershell:
& 'C:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\MSBuild\Current\Bin\MSBuild.exe' /p:PlatformToolset=v142`;WindowsTargetPlatformVersion=10`;Configuration=Release`;Platform=x64 .\SoloudStatic.vcxproj
but you can compile how you want. just make sure that it's architecture is really x64. you can check it with this command:
dumpbin /headers soloud_static_x64.lib | more
finally just link it with your nim file. add this line to the top:
{.link:"soloud_static_x64.lib".}
and compile nim file with this command:
nim c --cc:vcc --dynlibOverride:libsoloud.dll -r "examples\00-ogg\Example00_ogg.nim"

How to run an aleph program with Swi-prolog?

I’m trying to work Aleph with Swi-prolog. Are there any one could please tell me how to run this program if I have a file named train.pl (including the background and positive and negative examples.) What can I do to induce my program and get the output? By the way, I have already downloaded Aleph.pl for my program. When I ran it, it showed like this:
ERROR: c:/users/mac/downloads/aleph.pl:97:
Wrong context: arithmetic_function/1 can only be used in a directive
I also had similar problems. However, after some googling, I found a github repository which contains the aleph script that actually works (prolog/aleph.pl). However, the manual could be more detailed (at least for a newbie like me). A minimal working example that I have managed to run is the trains example (prolog/examples/train.pl) and I did the following:
Put the aleph.pl script into some directory path/to/dir
Put the train.pl script into the same directory.
Executing the following commands, one by one:
working_directory(_, 'path/to/dir').
consult('aleph.pl').
consult('trains.pl').
induce.
I ignored some errors and warnings that have appeared when executing the command consult('trains.pl').:
ERROR: path/to/dir/train.pl:16:
ERROR: source_sink `library(aleph)' does not exist
Warning: path/to/dir/train.pl:16:
Warning: Goal (directive) failed: user:use_module(library(aleph))

SWI-Prolog: No permission to load source when "Non-module file" already loaded into some module)

This error may be a duplicate of
SWI Prolog ensure_loaded error
Since that question is not fully answered, I decide to post mine here.
There are some dynamic loaded files using <name>:compile(Filename) clause, which I suspect could be a reason for the error.
➜ chill git:(master) ✗ swipl --traditional [18/06/20| 8:54AM]
Welcome to SWI-Prolog (threaded, 64 bits, version 7.6.4)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
Please run ?- license. for legal details.
For online help and background, visit http://www.swi-prolog.org
For built-in help, use ?- help(Topic). or ?- apropos(Word).
?- expects_dialect(sicstus).
true.
?- consult('chill-test.pl').
true.
?- set_prolog_flag(double_quotes, chars).
true.
?- run_trials('orig-db', 'raw250-split1.pl', 'orig-db-evaluate', 25, 200, 'raw250-res1.out').
Reading Split File: raw250-split1.pl
Specializing with 25 top-level examples
Beginning Example Analysis
Attempting Example 1 ....
<omitted output>
BEGINING INDUCTION: 1 5
ERROR: No permission to load source `'/home/vimos/git/SP/mooney/chill/orig-db.i'' (Non-module file already loaded into module test; trying to load into thetheory)
ERROR: In:
ERROR: [36] throw(error(permission_error(load,source,'/home/vimos/git/SP/mooney/chill/orig-db.i'),context(...,'Non-module file already loaded into module test; trying to load into thetheory')))
ERROR: [34] '$assert_load_context_module'('/home/vimos/git/SP/mooney/chill/orig-db.i',thetheory,[expand(false),...]) at /usr/lib/swi-prolog/boot/init.pl:2439
ERROR: [33] '$mt_do_load'(<clause>(0x559a46329ea0),'orig-db.i','/home/vimos/git/SP/mooney/chill/orig-db.i',thetheory,[expand(false),...]) at /usr/lib/swi-prolog/boot/init.pl:2069
ERROR: [32] setup_call_catcher_cleanup(system:with_mutex('$load_file',...),system:'$mt_do_load'(<clause>(0x559a46329ea0),'orig-db.i','/home/vimos/git/SP/mooney/chill/orig-db.i',thetheory,...),_142002,system:'$mt_end_load'(<clause>(0x559a46329ea0))) at /usr/lib/swi-prolog/boot/init.pl:443
ERROR: [21] make_theory('orig-db.i',op/2,_142072) at /home/vimos/git/SP/mooney/chill/spchillin-nr.pl:966
ERROR: [20] top_induction('orig-db.i',[op(...,_142120)],[op(...,_142132),...|...],_142108) at /home/vimos/git/SP/mooney/chill/spchillin-nr.pl:129
ERROR: [19] chill_lib:cpu_time(user:top_induction('orig-db.i',...,...,_142186),_142170) at /home/vimos/git/SP/mooney/chill/chill_lib.pl:136
ERROR: [18] induce_control_definition('orig-db.i',[op(...,_142230)],[op(...,_142242),...|...],_142216,_142218) at /home/vimos/git/SP/mooney/chill/chill.pl:109
ERROR: [17] add_each_optimization(cxit([...|...]),'orig-db.i',fail,[(... :- ...),...],[],_142282,_142284) at /home/vimos/git/SP/mooney/chill/chill.pl:85
ERROR: [14] add_rules_for_targets([tr(...,function,fail)],'orig-db.i',[... - ...,...|...],[],[],_142346,_142348) at /home/vimos/git/SP/mooney/chill/chill.pl:79
ERROR: [12] chill_lib:cpu_time(user:create_optimized_rules(...,'orig-db.i',_142426,_142428),_142412) at /home/vimos/git/SP/mooney/chill/chill_lib.pl:136
ERROR: [11] chill_specialize('orig-db','<garbage_collected>','orig-db.i','orig-db-opt.pl') at /home/vimos/git/SP/mooney/chill/chill.pl:11
ERROR: [9] run_trials_loop(25,'orig-db',225,200,[[...],...|...],[ti(...,...,...),...|...],'raw250-res1.out') at /home/vimos/git/SP/mooney/chill/chill-test.pl:188
ERROR: [7] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
^ Exception: (32) setup_call_catcher_cleanup(system:with_mutex('$load_file', '$mt_start_load'('/home/vimos/git/SP/mooney/chill/orig-db.i', <clause>(0x559a46329ea0), [expand(false), expand(true)])), system:'$mt_do_load'(<clause>(0x559a46329ea0), 'orig-db.i', '/home/vimos/git/SP/mooney/chill/orig-db.i', thetheory, [expand(false), expand(true)]), _142584, system:'$mt_end_load'(<clause>(0x559a46329ea0))) ? creep
^ Call: (34) call(system:'$mt_end_load'(<clause>(0x559a46329ea0))) ? creep
^ Exit: (34) call(system:'$mt_end_load'(<clause>(0x559a46329ea0))) ? creep
There are two dynamic compiled modules test and thetheory. They are both compiled from the same file orig-db.i.
If I force one of them to read from a different file like orig-db.ii, the error will be different.
I tried the same code with yap, it didn't complain with this error.
➜ chill git:(master) ✗ yap [18/06/20| 9:21AM]
% Restoring file /usr/lib/Yap/startup.yss
YAP 6.2.2 (x86_64-linux): Sat Sep 17 13:59:03 UTC 2016
?- consult('chill-test.pl').
yes
?- run_trials('orig-db', 'raw250-split1.pl', 'orig-db-evaluate', 25, 200, 'raw250-res1.out').
<omitted output>
BEGINING INDUCTION: 1 5
% reconsulting /home/vimos/git/SP/mooney/chill/orig-db.i...
% reconsulted /home/vimos/git/SP/mooney/chill/orig-db.i in module thetheory, 0 msec 1344 bytes
Induction Time: 0.00
op(ps([traverse(pvar(1),freevar):[],const(pvar(1),riverid(mississippi)):[mississippi],answer(pvar(0),state(pvar(0))):[which,through]],[run,?]),G9) :-
db_lib:coref_vars(traverse,2,2,answer,2,1,ps([traverse(pvar(1),freevar):[],const(pvar(1),riverid(mississippi)):[mississippi],answer(pvar(0),state(pvar(0))):[which,through]],[run,?]),G9).
op(A,B) :-
introduce(density(_,_),[density],A,B).
op(A,B) :-
db_lib:coref_vars(density,2,1,state,1,1,A,B).
op(A,B) :-
db_lib:coref_vars(density,2,2,smallest,2,1,A,B).
op(A,B) :-
db_lib:lift_conj(state,1,smallest,2,2,A,B).
op(A,B) :-
db_lib:drop_conj(density,2,smallest,2,2,A,B).
Replacing ensure_loaded to reconsult does not solve the error in Swi-Prolog.
I need some hint to understand this error, is this an implementation issue of Swi-Prolog?
If you want to try it, the code can be found from the ftp url below.
Thank you for the help!
I am trying to migrate an earlier code to SWI-Prolog, which was written in
SICStus 3 #3: Thu Sep 12 09:54:27 CDT 1996 or earlier
by Raymond J. Mooney ftp://ftp.cs.utexas.edu/pub/mooney/chill/.
All the questions with this tag are all related to this task. I'm new to prolog, helps and suggestions are welcomed!
This is a documented, current limitation of SWI-Prolog, related to its make mechanism. A possible workaround is to duplicate the orig-db.i file. This way the two modules, test and thetheory, will be loading different files.

Ignore undefined facts in SWI Prolog

I'm running queries against a generated set of facts, and some facts may not exist. When that happens, SWI Prolog errors out with e.g. Undefined procedure: 'LongIdent'/4. Is there a way to get it to instead simply have the goal involving 'LongIdent'/4 fail?
Well you could change the default behavior using unknown/2 which is declared as unknown(-Old, +New), Old is the old-current flag, New is the new flag that you use:
?- unknown(trace,fail).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
true.
?- a(1).
false.
But you see the warnings explaining that this may not be a good idea...
If you don't know the current/old flag you could use it like:
?- unknown(X,fail).
Warning: Using a non-error value for unknown in the global module
Warning: causes most of the development environment to stop working.
Warning: Please use :- dynamic or limit usage of unknown to a module.
Warning: See http://www.swi-prolog.org/howto/database.html
X = trace.

IBM MQ - AMQ6109: An internal WebSphere MQ error has occurred

I am trying to start queue manager on windows but getting error as AMQ6109 - An Internal WebSphere MQ has occurred.
WebSphere MQ queue manager 'IIB9QMGR' starting.
The queue manager is associated with installation 'Installation1'.
AMQ6109: An internal WebSphere MQ error has occurred.
Verified FDC and I could see below details
WebSphere MQ First Failure Symptom Report
Date/Time:- Tue October 17 2017 20:31:24 India Standard Time
UTC Time :- 1508252484.533000
UTC Time Offset :- 330 (UNKNOWN))
Operating System :- Windows 7 Enterprise x64 Edition, Build 7601:SP1
PIDS :- 724H7220
LVLS :- 7.5.0.1
Product Long Name :- WebSphere MQ for Windows
Vendor :-IBM
Installation Path :- C:\Program Files (x86)\IBM\WebSphere MQ
Installation Name :- Installation1 (1)
Probe Id :- ZC041040
Application Name :- MQM
Component :- zcsPipeCreate
SCCS Info :- F:\build\slot1\p750_P\src\libzc\amqzcsbn.c,
Line Number :1960
Build Date :- Mar8 2013
Build Level:-p750-001-130308
Build Type:- IKAP - (Production)
UserID:- spotlapelli
Process Name:- C:\Program Files (x86)\IBM\WebSphere MQ\bin\amqzxma0.exe
Addressing mode :- 32-bit
Process :- 00007924
Thread :- 00000001
QueueManager :- IIB9QMGR
UserApp :- FALSE
ConnId(1) IPCC :- 2
ConnId(2) QM :- 2
ConnId(3) QM-P :- 2
ConnId(4) App :- 2
Last HQC :- 2.0.0-575228
Last HSHMEMB :- 4.0.0-22980
Major Errorcode :- STOP
Minor Errorcode :- OK
Probe Type :- HALT6109
Probe Severity :- 1
Probe Description :- AMQ6109: An internal WebSphere MQ error has occurred
FDCSequenceNumber :- 0
Comment1 :- The filename, directory name, or volume label syntax is in incorrect
Comment2 :- \\.\pipe\1\IIB9QMGR\zsocketEC\Zagent
Performed below steps to resolve but did not worked
Restart PC and start queue manager
Uninstall and Install MQ
Given the limited amount of information posted here (no version, platform, other details), its a real challenge (but fortunately I like a challenge...)!
If I've calculated correctly, that probe comes out when a windows queue manager tries to create a named pipe and it fails (Probe 40 from zcsPipeCreate). It is quite rare of that call to fail, and not many causes - the only times it has been seen all turned out to be caused by external influences. A number of times stopping something called SWIFT application services avoided the problem (apparently there's a SWIFT update to it to fix this), although I have no idea what SWIFT Application Services are... If you are not running SWIFT, then you will need to open a PMR with IBM to debug further, although I would recommend updating this question with your full FDC header just in case anything else stands out.
The test program referred to in the link #JoshMc gave is as follows - perhaps try this?
#include <windows.h>
main()
{
HANDLE hnp;
int rc=0;
hnp = CreateNamedPipe("\\\\.\\pipe\\1\\TESTQMGR\\zsocketEC\\Zagent",
PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_WAIT, 1, 1024,1024,
NMPWAIT_USE_DEFAULT_WAIT, NULL);
rc=GetLastError();
if( hnp == INVALID_HANDLE_VALUE )
printf("CreateNamedPipe failed with %d ",rc );
else
printf("NamedPipe created successfully");
}

Resources