Ada - Incorrect use of "random" - ada

I'm trying to generate a random Positive in ada in my procedure. For this, I have the following code:
procedure Inicialize(K: Positive) is
package rand is new ada.numerics.discrete_random(Positive);
use rand;
G: Generator;
t: Positive;
begin
isInitialized:= True;
reset(G);
t := random(G); --error for this line
end Inicialize;
I get the error
incorrect use of "random"
I have no idea, how is this an incorrect use, or what does it even mean. Could someone please elaborate?
Thank you!

Assuming isInitialized is a global variable, that code looks legal as it stands. It compiles and runs correctly with a current Gnat Ada. Is the full procedure more complicated than this? Could G or random be being redeclared?
I see your earlier question which mentions a package random. So it's likely a name clash between the package name and the procedure name. Removing the 'use rand', or renaming the package, would cure this.

Related

Deep copy of function arguments for polymorphic types

I use an object based on a base package roughly defined as:
package Base is
type T_Base is abstract tagged null record;
-- This performs a deep copy. Shallow copies may lead to STORAGE_ERROR.
-- This shall be implemented by every derived type.
function Copy (From : in T_Base) return T_Base'Class is abstract;
end package Base;
This package is derived by several packages which are further derived
package Foo is
type T_Foo is new T_Base with record
A_Data : Natural; -- Of course, in the real code, these are types by far more complex.
end record;
procedure do_something (Foo_Object : in T_Foo);
-- This implements the deep copy
function Copy (From : in T_Foo) return T_Base'Class is abstract;
end package Foo;
On calling the procedure do_something, I do get a storage_error:
procedure handle_received_foo (Foo_In: in Foo.T_Foo) is
begin
Foo.do_something (Foo_Object => Foo_In); -- The storage error does happen here.
end main;
When running the code with gdb, I get a segfault on entering the function and I get:
Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 39 (LWP 39)]
0x033c9828 in foo.do_something (foo_object=...) at ./foo.adb:67
67 procedure do_something (Foo_Object : in T_Foo);
(gdb) p foo_object
$1 (null)
So I guess I get a storage_error when doing the shallow copy of the argument Foo_Object.
I am aware that this is no MWE and that there might be a mistake in one of the types present used in the derived types.
I can't find any good option:
Making T_Foo a Controlled type to call Copy in Adjust seems not to be possible without greatly changing its definition as I can't derive T_Foo both from T_Base and Ada.Finalization.Controlled since none of them is an interface types
Defining T_Base as
type T_Base is abstract new Ada.Finalization.Controlled with null record;
and override Adjust here seems to induce a hell lot too much modifications on the existing code base as gnat yields in multiple places
type of aggregate has private ancestor "Controlled" must use extension aggregate.
So I'm low on solutions to either investigate the problem further or to solve it with a hammer.
The problem was not in the Copy function. The comments I saw in the code base were misleading.
The fact that introducing new variables changed the location of the exception made me consider some stack overflow problems.
Indeed the Storage_Size allocated for the task was not sufficient. Increasing the pragma Storage_Size(<value>) solved the problem.
Since the code base is compiled with -fstack-check, this led to the aforementioned STORAGE_ERROR.
More infos on Adacore's documentation.
This could probably have been seen with Gem #95: Dynamic Stack Analysis in GNAT but I am not currently able to see any result with the binding option suggested therein.

CONSTRAINT_ERROR when using LCM function

I am trying to write a user defined task scheduling policy for Cheddar in ada language. but when i write the following code:
mul:=1.0;
for i in tasks_range loop
if tasks.ready(i)=true then
mul:=lcm(tasks.capacity(i),mul);
end if;
end loop;
It gives an error: Exception raised :CONSTRAINT_ERROR:expressions.adb:1876 access check failed
I tried defining mul as integer and it failed there too.
Please help.
There's a lot of info that we need in order to really give you any meaningful help.
As a guess, given the exception is Constraint_Error, I'd look at the range of tasks_range compared to tasks.ready & tasks.capacity. — Given that this doesn't look like idiomatic Ada code, I'm guessing you're either (a) trying to transcribe the method/algorithm from some other language, or (b) you are unfamiliar with Ada's task system.

How do you implement Generic_Sorting in Ada for a vector?

I'm trying to do some basic translations of old C++ code from many moons ago to learn Ada, and I have been absolutely stumped on how to sort a vector using the built-in Generic_Sorting. I haven't been able to find any concrete examples of it in action, the closest being a now-defunct Danish wiki article which looks like it would have had a full example but the archive didn't snatch it up: https://web.archive.org/web/20100222010428/http://wiki.ada-dk.org/index.php/Ada.Containers.Vectors#Vectors.Generic_Sorting
Here is the code as I thought it should work from the above link:
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
with Ada.Strings.Unbounded; use Ada.Strings.Unbounded;
with Ada.Containers.Vectors; use Ada.Containers;
procedure Vectortest is
package IntegerVector is new Vectors
(Index_Type => Natural,
Element_Type => Integer);
package IVSorter is new Generic_Sorting;
IntVec : IntegerVector.Vector;
Cursor : IntegerVector.Cursor;
begin
IntVec.Append(3);
IntVec.Append(43);
IntVec.Append(34);
IntVec.Append(8);
IVSorter.Sort(Container => IntVec);
Cursor := IntegerVector.First(Input);
while IntegerVector.Has_Element(Cursor) loop
Put(IntegerVector.Element(Cursor));
IntegerVector.Next(Cursor);
end loop;
end Vectortest;
I've tried so many different combinations of use and with but all I can get are various error codes. The above code gives Generic_Sorting is not visible, but when I try to explicitly state with Ada.Containers.Vectors.Generic_Sorting I get the error "Ada.Containers.Vectors.Generic_Sorting" is not a predefined library unit. I have no idea what I'm doing wrong here, I'm sure it's a fundamental misunderstanding of the way Ada brings in packages, and I hope that nailing this down will help me understand it a bit better.
Generic_Sorting is an inner package to Ada.Containers.Vectors and cannot be explicitly withed (as you have discovered). And since Ada.Containers.Vectors is itself a generic package, Generic_Sorting is an inner package to the instantiation of Ada.Containers.Vectors. So you can reach it by prefixing with the name of the instance:
package IVSorter is new IntegerVector.Generic_Sorting;

Can't understand how generics work

I have a package called Linked_List(.ads) Here is the code in it:
Generic
type T is private;
package Linked_List is
type List is tagged record
Data : T;
end record;
end Linked_List;
and here is the code in the package which contains the main function (main.adb)
with Ada.Text_IO; use Ada.Text_IO;
with Linked_List;
procedure Main is
type ListOfIntegers is new Linked_List(T => Integer);
begin
null;
end Main;
I'm getting this error:
4:30 subtype mark required in this context
found "Linked_List" declared at linked_list.ads:3
found "Linked_List" declared at linked_list.ads:3
4:41 incorrect constrain for this kind of type
Any help is appreciated.
new Linked_List(T => Integer) defines a new package, not a new type. The error messages you’re getting are because the compiler thinks you’re declaring a type, so seeing the name of a package at column 30 confused it; it wanted to see the name of a (sub)type.
Line 4 should read
package ListOfIntegers is new Linked_List(T => Integer);
after which there is a type ListOfIntegers.List, so you can write
My_List : ListOfIntegers.List;
You may find having to say ListOfIntegers. all the time annoying; you can say
use ListOfIntegers;
after which you can just write
My_List : List;
but it’s usually thought best not to overdo this (if you have dozens of “withed” packages, “using” them all makes it difficult to know which one you’re referring to).
By the way, normal Ada usage is to use underscores to separate words in identifiers: List_Of_Names.

How to print integers in ada83 environment

I want to print integers in Ada 83. At present I am just using 'with Text_IO' and 'use Text_IO'. I don't want to print using the Integer'Image option. I want to use Integer_Text_IO in ada83. Please help me out with the syntax.
I am using below code:
with Text_IO;
use Text_IO;
i: INTEGER :=1;
package Int_IO is new Integer_IO(INTEGER);
use Int_IO; put(i);
I am getting 'expect signed integer type in instantiation of "Num" ' error.
The example below, which compiles, should help.
But please, when posting a question on StackOverflow (or anywhere on the Net, really) show us the code you’ve actually tried. The sample you’ve provided doesn’t come close to compiling (it fails at line 3 with compilation unit expected), and that makes it very hard for us to work out how to help you.
You’ll get expect signed integer type in instantiation of “Num” if you try to instantiate Text_IO with the wrong sort of type (for example, Float).
with Text_IO;
procedure Integer_IO_Demo is
package Int_IO is new Text_IO.Integer_IO (Integer);
begin
for J in 5 .. 10 loop
Int_IO.Put (J);
Text_IO.New_Line;
end loop;
end Integer_IO_Demo;

Resources