"ADA.FLOAT_IO" is not a predefined library unit - ada

Why do i get this error?
"ADA.FLOAT_IO" is not a predefined library unit
I've never written anything in ADA before, simply i have no idea what i'm doing. I use GNAT to compile.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Float_IO; use Ada.Float_IO;
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;
procedure MAIN is
A,B,C:Float;
W : Float;
Re, Im:Float;
begin
Put("Give A");Get(A);
Put("Give B");Get(B);
Put("Give C");Get(C);New_Line;
if A=0.0 then
Put_Line("It is not second degree polynomial");
else
W:=B*B - 4.0*A*C;
Re:=B/(2.0*A); Im:=Sqrt(Abs(W))/(2.0*A);
Put("dif = "); Put(W);New_Line;
if W<0.0 then
Put_Line("Complex ");
Put("x1 = ");Put(-Re);Put(" -j ");Put(Im);Put(" ");
Put("x2 = ");Put(-Re);Put(" +j ");Put(Im);New_Line;
else
Put_Line("Real");
Put("x1 = ");Put(-Re-Im);Put(" ");
Put("x2 = ");Put(-Re+Im);
end if;
end if;
end MAIN;

IIRC Float_IO is a child of Text_IO: Ada.Text_IO.Float_IO. Furthermore, that's a generic package. I guess you want Ada.Float_Text_IO, which is defined as
package Ada.Float_Text_IO is new Ada.Text_IO.Float_IO (Float);

Related

Ada - How do you read an array from a single line of input?

My question is pretty simple, I have input that looks like this...
0 0 0 1 1 1 -1 -1 -1 1
And I need to store these values into an array but I can't figure it out. This is what I have so far...
with Ada.Text_IO; use Ada.Text_IO;
procedure Main is
type arr is array(1..10) of Integer;
Data : arr;
begin
for I in 1..arr'Length loop
Data(I) := Integer'Value(Get_Line);
end loop;
end Main;
I know this wrong and it's pretty obvious why this isn't working. I'm trying to store multiple values into a single integer, I need a way to iterate over the input or load all the values at once. How would you do this in Ada?
You can use Get_Line to get the whole line as a string and then Ada.Integer_Text_IO to parse the string:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Hello is
Line : String := Get_Line;
Value : Integer;
Last : Positive := 1;
begin
while Last < Line'Last loop
Get(Line(Last..Line'Last),Value,Last);
Put_Line(Value'Image); -- Save the value to an array here instead
Last := Last + 1; -- Needed to move to the next part of the string
end loop;
end Hello;
After that, you can load the values into an array in the loop or however you like.
Example output:
$gnatmake -o hello *.adb
gcc -c hello.adb
gnatbind -x hello.ali
gnatlink hello.ali -o hello
$hello
0
0
0
1
1
1
-1
-1
-1
1
EDIT: Adding a recursive option that is more general. This will read a line from STDIN and recursively concatenate the values into an array. It uses the secondary stack to do so in GNAT.
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_Io;
procedure Hello is
-- Need an array return type
type Integer_Array is array (Positive range <>) of Integer;
-- Recursive function
function Get_Ints return Integer_Array is
Value : Integer;
begin
-- Read from STDIN using Integer_Text_IO;
Get(Value);
-- Concatinate recursively
return Integer_Array'(1 => Value) & Get_Ints;
exception
-- I found different exceptions with different versions
-- of GNAT, so using "others" to cover all versions
when others =>
-- Using Ada2012 syntax here. If not using Ada2012
-- then just declare the Empty variable somewhere
-- and then return it here
return Empty : Integer_Array(1..0);
end Get_Ints;
Result : Integer_Array := Get_Ints;
begin
Put_Line("Hello, world!");
Put_Line(Integer'Image(Result'Length));
for E of Result loop
Put(Integer'Image(E) & " ");
end loop;
end Hello;
If you know that you have 10 elements to read, it can be done a little more simply like this:
with Ada.Text_IO; use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;
procedure Hello is
A: array (1..10) of Integer;
begin
for V of A loop
Get(V);
end loop;
for I in A'Range loop
Put(I, 5);
Put(": ");
Put(A(I), 5);
New_Line;
end loop;
end Hello;
If you don't actually know how many elements to read in advance, please update the question.
Even though this already was answered, I'd like to add a couple improvements to Jere's answer.
It is more Ada-like to terminate the recursion using End_Of_File rather than an exception. Plus, it makes the program clearer.
Also, using tail-call recursion instead of normal recursion allows the compiler to perform some optimization.
function Get_Ints(input : in File_Type) return Integer_Array is
function Get_Ints_Rec(accumulator : in Integer_Array) return Integer_Array is
value : Integer;
begin
if End_Of_File(input) then
return accumulator;
else
begin
Get(input, value);
exception
when Data_Error => -- problem when reading
if not End_Of_Line(input) then
Skip_Line(input);
end if;
return Get_Ints_Rec(acc);
end;
return Get_Ints_Rec(accumulator & (1 => value));
end if;
end Get_Ints_Rec;
acc : constant Integer_Array(1 .. 0) := (others => 0);
begin
return Get_Ints_Rec(acc);
end Get_Ints;

Tasking in SPARK requires sequential elaboration

I'm currently learning Ada during a university course on real-time programming languages and have a question about SPARK.
I'm working on a project with a task that monitors an off-grid power supply. This task is crucial for machine safety and should therefore be as error free as possible, say proven with SPARK.
I get this weird error that I was not able to find a fix for 11:14 tasking in SPARK requires sequential elaboration (SPARK RM 9(2)) violation of pragma SPARK_Mode
The original code is a little long but I was able to get the same error with a minimal example.
The specification:
pragma Profile (Ravenscar);
pragma SPARK_Mode;
with System;
package simple_monitoring is
function sign (val : in Float) return Float
with Pre => val >= 10.0;
task type myTask is
end myTask;
end simple_monitoring;
The implementation:
pragma Profile (Ravenscar);
pragma SPARK_Mode;
with Ada.Real_Time; use Ada.Real_Time;
with Ada.Text_IO; use Ada.Text_IO;
package body simple_monitoring is
function sign (val : in Float) return Float is
res : Float;
begin
pragma Assert (val >= 10.0);
res := 100.0 / val;
return res;
end sign;
task body myTask is
TASK_PERIOD : constant Time_Span := Milliseconds (100);
next_time : Time := Clock;
myVar : Float;
begin
loop
Put_Line ("Running task");
myVar := sign (20.0);
next_time := next_time + TASK_PERIOD;
delay until next_time;
end loop;
end myTask;
end simple_monitoring;
Any help is appreciated :-)
You need the extra configuration pragma
pragma Partition_Elaboration_Policy (Sequential);
(see ARM H.6). For the example you give, this only needs to be placed on the spec; but in general it needs to be a program-wide configuration pragma.
You arrange this by having a file, say gnat.adc, containing for example
pragma Profile (Ravenscar);
pragma Partition_Elaboration_Policy (Sequential);
and referencing it in package Builder in your GNAT project file:
package Builder is
for Global_Configuration_Pragmas use "gnat.adc";
...

Ada non-visible declaration error

I am receiving a "non-visible declaration" error on my Generator. I am converting this code from a single procedure to using multiple procedures and functions.
I have truncated the code a bit Any explanation of the non-visible declaration error would be appreciated.
The non visible declaration error is occurring in this block of code:
WITH Ada.Integer_Text_IO;
USE Ada.Integer_Text_IO;
WITH Ada.Text_IO;
USE Ada.Text_IO;
WITH Ada.Strings;
USE Ada.Strings;
WITH Ada.Numerics.Discrete_Random;
PROCEDURE Project IS
SUBTYPE Guess IS Integer RANGE 1 .. 25;
G : Generator;
CorrectAnswer : Guess;
UserGuess : Guess;
BEGIN
Reset (G);
CorrectAnswer := Random(G);
FOR I IN 1..3 LOOP
GetUserGuess(UserGuess);
PrintCorrectAns(CorrectAnswer);
IF IsCorrect(UserGuess) THEN
Put("You Win!");
ELSE
Put("You Lose!");
END IF;
END LOOP;
End Project;
The non-visible declaration at a-nudira.ads:48 and 50 (line numbers may vary with compiler release) are because Ada.Numerics.Discrete_Random, see ARM A.5.2(16), is a generic package and needs to be instantiated with whichever discrete type you need.
In your case, I guess that’s Guess:
package RNG is new Ada.Numerics.Discrete_Random (Result_Subtype => Guess);
use RNG;

Ada Text_IO Put printing out after Get

I am trying to get a character input from the user in this format:
Player 1: a
This is my code:
Ada.Text_IO.Put("Player"&Integer'Image(board.turn)&": ");
Ada.Text_IO.Get(Item => move);
Now, when I run my program this is what happens:
a
Player 1:
For some odd reason, the GET is appearing before the PUT... I tried flipping their positions and it still occurs the same way.
I recently upgraded my AdaCore GNAT from 2012 to 2014 and I didn't have this issue in 2012...
Am I missing something?
Please help!
These are my with/use if you need them:
with Ada.Text_IO, Ada.Characters.Handling;
with Ada.Exceptions; use Ada.Exceptions;
USE Ada, Ada.Text_Io;
NEW
Here is more code... Don't worry about the AI stuff...
Full code:
PROCEDURE Main IS
PACKAGE board is new connectfour;
USE board;
begin
PUT(" ********** CONNECT-FOUR *********"); Put_Line("");
AI.start;
while (not board.isFull) loop
if AIwin = true then goto Win; end if;
Put_Line(""); DELAY 0.5;
Put("Player"&Integer'Image(board.turn)&": ");
Get(move);
if move='0' then goto Quit; end if;
Put_Line("");
if board.Move(move) = true then goto Win; end if;
board.print; DELAY 0.5;
AI.print;
end loop;
<<Win>>
Put_Line("");
Put_Line("PLAYER"&Integer'Image(board.turn)&" IS THE WINNER!");
<<Quit>>
AI.stop;
Put_Line("");
if move='0' then
Put_Line("PLAYER"&Integer'Image(board.turn)&" HAS FORFEIT!");
if board.turn = 1 then
Put_Line("PLAYER 2 IS THE WINNER!");
else
Put_Line("PLAYER 1 IS THE WINNER BY DEFAULT!");
end if;
end if;
end Main;
The standard output may be being buffered. Try
Ada.Text_IO.Put("Player"&Integer'Image(board.turn)&": “);
Ada.Text_IO.Flush;
Ada.Text_IO.Get(Item => move);
(later)
Well, that wasn’t the answer. I just tried
with Ada.Text_IO;
procedure Borovez is
Move : Character;
begin
Ada.Text_IO.Put ("Player" & Integer'Image (42) & ": ");
-- Ada.Text_IO.Flush;
Ada.Text_IO.Get (Item => Move);
end Borovez;
on GNAT GPL 2014/Windows 7 and it worked exactly as expected.
You’re going to need to edit your question to include a Minimal, Complete, and Verifiable example.

Ada sin(x) Computing with Taylor-series

I'm an absolute beginner in Ada and I'm trying to calculate sin(x) [sin(3) now] by using Taylor-series, but I just can't get it to work.
So here is my procedure:
with Ada.Float_Text_IO;
with Mat;
procedure SinKoz is
X:Float:=3.0;
Szamlalo:Float:=0.0;
begin
for I in 1..100 loop
Szamlalo := Szamlalo + ((-1.0)**I)*(X**(2.0*I+1.0))/Mat.Faktorialis(2*I+1);
end loop;
Ada.Float_Text_IO.Put( Szamlalo );
end SinKoz;
And inside Mat, here is my Faktorialis, which calculates the factorial of 2*I+1:
function Faktorialis( N: Float ) return Float is
Fakt : Float := 1.0;
begin
for I in 1..N loop
Fakt := Fakt * I;
end loop;
return Fakt;
end Faktorialis;
When i'm trying to compile my code, this error comes up:
exponent must be of type Natural, found type "Standard.Float"
I hope you can help me trying to figure out what went wrong with my types!
The first question is : do you need to raise X to a non-integer power?
It looks to me as if you don't : in which case replace X**(2.0*I+1.0) with X**(2*I+1) and all will be well.
But if you really do (perhaps not here, but in another application) you just need to make such an operator visible : there's one for Float in the package Ada.Numerics.Elementary_Functions so precede your function with
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;
and it should work as written.
Finally, if you have created your own float type, you can instantiate the generic package Ada.Numerics.Generic_Elementary_Functions with your type as its parameter, to create a set of these functions specifically for your type.
Gotta love Ada's strong typing.
Off the top of my head, I suspect your problem may be this line:
Szamlalo := Szamlalo + ((-1.0)**I)*(X**(2.0*I+1.0))/Mat.Faktorialis(2*I+1);
2.0*I+1.0 is going to return a Float. Not a Natural. You could try wrapping that in Integer() or Natural() (Natural is a subtype of Integer) and see if that helps.

Resources