I want to use the result from the analysis of Value plugin in Frama-C (batch mode) for further evaluation of variables in functions. However, the output seems to be large with lots of [value] tags, what I need is only the part from [value] ====== VALUES COMPUTED ====== with computed values at the end of each function. Does Frama-C support the options that allow me to do that?
You may find that the command-line options frama-c -no-val-show-initial-state -no-val-show-progress … make the output more to your taste.
When using the latter option, you may appreciate -val-print-callstacks, which prints each time a message is emitted the call-stack the message corresponds to, since that context is no longer available from the previous lines in the log.
For illustration, the development version of Frama-C at the time of answering shows the messages below by default:
int x;
/*# assigns x; */
void f(void);
void g(int y) {
f();
x += y;
}
int main(void) {
g(1);
}
Analyzing with frama-c -val t.c:
[value] Analyzing a complete application starting at main
[value] Computing initial state
[value] Initial state computed
[value] Values of globals at initialization
x ∈ {0}
[value] computing for function g <- main.
Called from t.c:12.
[value] computing for function f <- g <- main.
Called from t.c:7.
[value] using specification for function f
t.c:3:[value] warning: no \from part for clause 'assigns x;' of function f
[value] Done for function f
t.c:8:[kernel] warning: signed overflow. assert x+y ≤ 2147483647;
[value] Recording results for g
[value] Done for function g
[value] Recording results for main
[value] done for function main
[value] ====== VALUES COMPUTED ======
[value] Values at end of function g:
x ∈ [-2147483647..2147483647]
[value] Values at end of function main:
x ∈ [-2147483647..2147483647]
__retres ∈ {0}
Analyzing with frama-c -val t.c -no-val-show-initial-state -no-val-show-progress:
[value] Analyzing a complete application starting at main
[value] Computing initial state
[value] Initial state computed
[value] using specification for function f
t.c:3:[value] warning: no \from part for clause 'assigns x;' of function f
t.c:8:[kernel] warning: signed overflow. assert x+y ≤ 2147483647;
[value] done for function main
[value] ====== VALUES COMPUTED ======
[value] Values at end of function g:
x ∈ [-2147483647..2147483647]
[value] Values at end of function main:
x ∈ [-2147483647..2147483647]
__retres ∈ {0}
And adding the option -val-show-callstack means that for the alarm at line 8, the context is shown as below:
t.c:8:[kernel] warning: signed overflow. assert x+y ≤ 2147483647;
stack: g :: t.c:12 <- main
Related
As the title says, I am trying to use logShow inside of my handleAction function.
I imported the Effect.Console (logShow)
and tried to use it like this, everytime a button is clicked:
handleAction ∷ forall o m. Action → H.HalogenM State Action () o m Unit
handleAction = case _ of
Update -> do
logShow "Hello"
H.modify_ \st -> st { field3 = st.field3 + 1 }
But I only get the following Error, and I don't understand very much, as I am very new to purescript and functional programming at all.
Could not match type
Effect
with type
HalogenM
{ field1 :: Int
, field2 :: Int
, field3 :: Int
}
Action
()
o0
m1
while trying to match type Effect t2
with type HalogenM
{ field1 :: Int
, field2 :: Int
, field3 :: Int
}
Action
()
o0
m1
Unit
while checking that expression (discard (logShow "Hello")) (\$__unused -> modify_ (\st -> ... ))
has type HalogenM
{ field1 :: Int
, field2 :: Int
, field3 :: Int
}
Action
()
o0
m1
Unit
in value declaration handleAction
where m1 is a rigid type variable
bound at (line 77, column 16 - line 80, column 51)
o0 is a rigid type variable
bound at (line 77, column 16 - line 80, column 51)
t2 is an unknown type
PureScript(TypesDoNotUnify)
I am glad about any clue.
I'm not an expert in PS but I'll try my best to answer it. So please correct me if I'm wrong:
logShow type signature is MonadEffect m => Show a => a -> m Unit, means that the caller of this function should have an instance of or be constrained by MonadEffect.
In your case, handleAction has a type signature of forall o m. Action → H.HalogenM State Action () o m Unit and you call logShow inside it. Your m here doesn't describe any particular monad while as we knew already, the caller of logShow should be constrained by MonadEffect.
There are a couple of ways to solve this:
You can add MonadEffect constraint to your handleAction type signature like so
forall o m. (MonadEffect m) => Action → H.HalogenM State Action () o m Unit
This should work since HalogenM has instance of MonadEffect as long as your m also has MonadEffect instance. See here
Change your m to Aff as Aff has instance of MonadEffect. IIRC, Halogen requires your m to be or has an instance of Aff
Or you could use your own monad stack that has an instance of Aff as you can see in Thomas' great repository here
EDIT: The explanation above assumes you import logShow from Effect.Class.Console
But if you're using logShow from Effect.Console which has type signature Show a => a -> Effect Unit, then we need some function that converts the Effect monad to your m (this function should have type sig Effect a -> m a). And liftEffect is exactly what you're looking for.
handleAction :: forall o m. (MonadEffect m) => Action → H.HalogenM State Action () o m Unit
handleAction _ = do
liftEffect $ logShow "something"
...
Hope this helps :)
Specification:
package PolyPack with SPARK_Mode is
type Vector is array (Natural range <>) of Integer;
function RuleHorner (X: Integer; A : Vector) return Integer
with
Pre => A'Length > 0 and A'Last < Integer'Last;
end PolyPack ;
I want to write body of PolyPack package with Assert and loop_invariants that the gnatprove program can prove my function RuleHorner correctness.
I write my function Horner but I don;t know how put assertions and loop_invariants in this program to prove its corectness :
with Ada.Integer_Text_IO;
package body PolyPack with SPARK_Mode is
function RuleHorner (X: Integer; A : Vector) return Integer is
Y : Integer := 0;
begin
for I in 0 .. A'Length - 1 loop
Y := (Y*X) + A(A'Last - I);
end loop;
return Y;
end RuleHorner ;
end PolyPack ;
gnatprove :
overflow check might fail (e.g. when X = 2 and Y = -2)
overflow check might fail
overflow check are for line Y := (Y*X) + A(A'Last - I);
Can someone help me how remove overflow check with loop_invariants
The analysis is correct. The element type for type Vector is Integer. When X = 2, Y = -2, and A(A'Last - I) is less than Integer'First + 4 an underflow will occur. How do you think this should be handled in your program? Loop invariants will not work here because you cannot prove that an overflow or underflow cannot occur.
Is there a way you can design your types and/or subtypes used within Vector and for variables X and Y to prevent Y from overflowing or underflowing?
I am also curious why you want to ignore the last value in your Vector. Are you trying to walk through the array in reverse? If so simply use the following for loop syntax:
for I in reverse A'Range loop
I've written a rudimentary algorithm in Fortran 95 to calculate the gradient of a function (an example of which is prescribed in the code) using central differences augmented with a procedure known as Richardson extrapolation.
function f(n,x)
! The scalar multivariable function to be differentiated
integer :: n
real(kind = kind(1d0)) :: x(n), f
f = x(1)**5.d0 + cos(x(2)) + log(x(3)) - sqrt(x(4))
end function f
!=====!
!=====!
!=====!
program gradient
!==============================================================================!
! Calculates the gradient of the scalar function f at x=0using a finite !
! difference approximation, with a low order Richardson extrapolation. !
!==============================================================================!
parameter (n = 4, M = 25)
real(kind = kind(1d0)) :: x(n), xhup(n), xhdown(n), d(M), r(M), dfdxi, h0, h, gradf(n)
h0 = 1.d0
x = 3.d0
! Loop through each component of the vector x and calculate the appropriate
! derivative
do i = 1,n
! Reset step size
h = h0
! Carry out M successive central difference approximations of the derivative
do j = 1,M
xhup = x
xhdown = x
xhup(i) = xhup(i) + h
xhdown(i) = xhdown(i) - h
d(j) = ( f(n,xhup) - f(n,xhdown) ) / (2.d0*h)
h = h / 2.d0
end do
r = 0.d0
do k = 3,M r(k) = ( 64.d0*d(k) - 20.d0*d(k-1) + d(k-2) ) / 45.d0
if ( abs(r(k) - r(k-1)) < 0.0001d0 ) then
dfdxi = r(k)
exit
end if
end do
gradf(i) = dfdxi
end do
! Print out the gradient
write(*,*) " "
write(*,*) " Grad(f(x)) = "
write(*,*) " "
do i = 1,n
write(*,*) gradf(i)
end do
end program gradient
In single precision it runs fine and gives me decent results. But when I try to change to double precision as shown in the code, I get an error when trying to compile claiming that the assignment statement
d(j) = ( f(n,xhup) - f(n,xhdown) ) / (2.d0*h)
is producing a type mismatch real(4)/real(8). I have tried several different declarations of double precision, appended every appropriate double precision constant in the code with d0, and I get the same error every time. I'm a little stumped as to how the function f is possibly producing a single precision number.
The problem is that f is not explicitely defined in your main program, therefore it is implicitly assumed to be of single precision, which is the type real(4) for gfortran.
I completely agree to the comment of High Performance Mark, that you really should use implicit none in all your fortran code, to make sure all object are explicitely declared. This way, you would have obtained a more appropriate error message about f not being explicitely defined.
Also, you could consider two more things:
Define your function within a module and import that module in the main program. It is a good practice to define all subroutines/functions within modules only, so that the compiler can make extra checks on number and type of the arguments, when you invoke the function.
You could (again in module) introduce a constant for the precicision and use it everywhere, where the kind of a real must be specified. Taking the example below, by changing only the line
integer, parameter :: dp = kind(1.0d0)
into
integer, parameter :: dp = kind(1.0)
you would change all your real variables from double to single precision. Also note the _dp suffix for the literal constants instead of the d0 suffix, which would automatically adjust their precision as well.
module accuracy
implicit none
integer, parameter :: dp = kind(1.0d0)
end module accuracy
module myfunc
use accuracy
implicit none
contains
function f(n,x)
integer :: n
real(dp) :: x(n), f
f = 0.5_dp * x(1)**5 + cos(x(2)) + log(x(3)) - sqrt(x(4))
end function f
end module myfunc
program gradient
use myfunc
implicit none
real(dp) :: x(n), xhup(n), xhdown(n), d(M), r(M), dfdxi, h0, h, gradf(n)
:
end program gradient
I am new to Fortran and I have the following code, it basically solves a simple quadratic equation and output the solutions
!solving ax^2 + bx + c = 0
program output
implicit none
real :: a,b,c
character :: response
do
print*, 'Enter three coefficients a,b and c'
read *, a,b,c
call quad(a,b,c)
print*, 'Press Y to continue. Anykey for otherwise'
read *, response
if ( response /= 'y' .and. response /= 'Y') stop
end do
end program output
!Function to calculate Xs
subroutine quad(a,b,c)
implicit none
real :: a,b,c,xplus, xminus
xplus = ((-b)+sqrt((b**2)-(4*a*c)))/(2*a)
xminus = ((-b)-sqrt((b**2)-(4*a*c)))/(2*a)
if (xplus == xminus) then
print*, 'There exists 1 root only: '
write(*,12) xplus
12 format(2f10.2)
else
print*, 'Solutions of quadratic equation are'
write(*,10) xplus, xminus
10 format(1f10.5)
end if
end subroutine quad
This works. However, how would I go about with complex solutions. I.e, how would this line change, to make the format for complex numbers.
10 format(1f10.5)
Thank you so much.
I wrote a recursive program on Fortran to calculate the combinations of npoints of ndim dimensions as follows. I first wrote this program on MATLAB and it was perfectly running. But in Fortran, my problem is that after the first iteration it is assigning absurd values for the list of points, with no explanation. Could somebody give me a hand?
PROGRAM MAIN
IMPLICIT NONE
INTEGER :: ndim, k, npontos, contador,i,iterate, TEST
integer, dimension(:), allocatable :: pontos
print*, ' '
print*, 'npoints?'
read *, npontos
print*, 'ndim?'
read *, ndim
k=1
contador = 1
open(450,file= 'combination.out',form='formatted',status='unknown')
write(450,100) 'Comb ','stat ',(' pt ',i,' ',i=1,ndim)
write(450,120) ('XXXXXXXXXX ',i=1,ndim+1)
allocate(pontos(ndim))
do i=1,4
pontos(i)=i
end do
TEST = iterate(pontos, ndim, npontos,k,contador)
end program MAIN
recursive integer function iterate(pontos, ndim, npontos, k,contador)
implicit NONE
integer, intent(in) :: ndim, k, npontos
integer,dimension(:) :: pontos
integer contador,inic,i,j,m
if (k.eq.ndim) then
inic=pontos(ndim)
do i = pontos(ndim),npontos
pontos(k)= i
write(*,*) pontos(:)
contador=contador+1
end do
pontos(ndim)= inic + 1
else
inic = pontos (k)
do j = pontos(k),(npontos-ndim+k)
pontos(k)=j
pontos= iterate(pontos, ndim, npontos, k+1,contador)
end do
end if
pontos(k)=inic+1;
if (pontos(k).gt.(npontos-ndim+k+1)) then
do m =k+1,ndim
pontos(m)=pontos(m-1)+1
end do
end if
end function iterate
There are too many issues in that code... I stopped debugging it. This is what I got so far, it's too much for a comment.
This doesn't make sense:
pontos= iterate(pontos, ndim, npontos, k+1,contador)
You are changing pontos inside iterate, and never set a return value within the function.
You need to a) provide a result statement for recursive functions (and actually set it) or b) convert it to a subroutine. Since you are modifying at least one dummy argument, you should go with b).
Since you are using assumed-shape dummy arguments, you need to specify an interface to the function/subroutine, either explicitly or with a module.
Neither format 100 nor format 120 are specified in your code.