In my case,
If the value of a bit is "1" then my constraint will have a higher weight for '1', if the bit is "0" then my constraint will have higher weight for '0'. How to constraint it?
I get a syntax error for this piece code
rand bit value;
bit x; // Has either 1 or 0 depending on external signal
constraint constraint_c { value dist { x := 3, ~x := 1};};
Please help me on this. Thank you :)
You can put an if-else in a constraint
rand bit value;
bit x;
constraint c {
if(x)
value dist {1 := 3, 0 := 1};
else
value dist {1 := 1, 0 := 3};
}
Your weights can also be variables
int weight0, weight1;
constraint c {
value dist {1 := weight1, 0 := weight0};
// set before calling randomize
if (x) begin
weight1 = 3; weight0 =1;
end else begin
weight1 = 1; weight0 =3;
end
Or expressions
constraint c {
value dist {1 := x?3:1, 0 := x?1:3};
Related
I am working on the following proof and the invariant result_val is proved with an induction strategy on i using begin as the base case.
The sup case is trying to prove true which holds trivially using Frama-C 24.0. But when I switch to 25.0, it tries to prove a seemingly more complicated condition, which looks closer to a correct inductive inference because it did the weakest precondition computation explicitly.
However, all SMT solvers I tried cannot prove the condition generated by Frama-C 25.0.
I am a bit worried about the correctness of version 24.0's result because using true as the inductive proof goal seems to be unlikely. Can anyone hint to me at what happened? Is that a bug in 24.0 or just some difference in the implementation?
#include <stdbool.h>
#define SIZE 1000
bool data[SIZE] ;
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : (data[begin]==true) ? count(begin+1, end)+1 : count(begin+1, end);
*/
/*#
requires SIZE > begin >= 0;
requires SIZE >= end >= 0;
requires begin <= end;
assigns \nothing;
ensures \result == count(begin, end);
*/
unsigned int occurrences_of(int begin, int end)
{
unsigned int result = 0;
/*#
loop invariant i_bound: begin <= i <= end;
loop invariant result_bound: 0 <= result <= i-begin;
loop invariant result_val: result == count(begin, i);
loop assigns i, result;
loop variant end-i;
*/
for (unsigned int i = begin; i < end; ++i){
result += (data[i] == true) ? 1 : 0;
}
return result;
}
Below is the result from Frama-c 24.0
Proof:
Goal Invariant 'result_val' (preserved) (Induction: proved)
+ Goal Induction (Base) (proved)
+ Goal Induction (Induction (sup)) (proved)
+ Goal Induction (Induction (inf)) (proved)
Qed.
--------------------------------------------------------------------------------
Goal Induction (Induction (sup)):
Prove: true.
Below is the result from Frama-c 25.0
--------------------------------------------------------------------------------
Proof:
Goal Invariant 'result_val' (preserved) (Induction: pending)
+ Goal Induction (Base) (proved)
+ Goal Induction (Induction (sup)) (pending)
+ Goal Induction (Induction (inf)) (proved)
End.
--------------------------------------------------------------------------------
Goal Induction (Induction (sup)):
Let x_0 = to_uint32(end#L1).
Let x_1 = to_uint32(tmp#L12).
Let x_2 = data#L1[i#L6].
Let x_3 = result#L6.
Let x_4 = result#L13.
Let x_5 = to_uint32(1 + i#L6).
Assume {
Have: begin#L1 < i#L6.
Have: i#L6 <= end#L1.
Have: i#L6 < x_0.
Have: 0 <= x_3.
Have: x_5 <= end#L1.
Have: begin#L1 <= x_5.
Have: (begin#L1 + x_3) <= i#L6.
Have: (begin#L1 + x_4) <= x_5.
Have: is_uint32(i#L6).
Have: is_bool(x_2).
Have: is_uint32(x_3).
Have: if (x_2 = 1) then (tmp#L12 = 1) else (tmp#L12 = 0).
Have: forall i_0 : Z. let x_6 = L_count(data#L1, begin#L1, i_0) in
let x_7 = to_uint32(1 + i_0) in let x_8 = to_uint32(x_1 + x_6) in
let x_9 = data#L1[i_0] in ((i_0 <= end#L1) -> ((begin#L1 <= i_0) ->
((i_0 < i#L6) -> ((i_0 < x_0) -> ((0 <= x_6) -> ((x_7 <= end#L1) ->
((begin#L1 <= x_7) -> (((begin#L1 + x_6) <= i_0) ->
(((begin#L1 + x_8) <= x_7) -> (is_uint32(i_0) -> (is_bool(x_9) ->
(is_uint32(x_6) ->
((if (x_9 = 1) then (tmp#L12 = 1) else (tmp#L12 = 0)) ->
(L_count(data#L1, begin#L1, x_7) = x_8)))))))))))))).
[...]
Stmt { L6: }
Stmt { tmp = tmp_0; }
Stmt { L12: result = x_4; }
Stmt { L13: }
}
Prove: L_count(data#L1, begin#L1, x_5) = x_4.
Goal id: typed_occurrences_of_loop_invariant_result_val_preserved
Short id: occurrences_of_loop_invariant_result_val_preserved
--------------------------------------------------------------------------------
Prover Alt-Ergo 2.4.2: Timeout (Qed:52ms) (10s).
A bug on the typing of the induction tactic was indeed fixed between Frama-C 24 and 25 (https://git.frama-c.com/pub/frama-c/-/commit/6058453cce2715f7dcf9027767559f95fb3b1679). And the symptom was indeed that the tactic could generate ill-typed formulas with true instead of a term.
Proving this example in not that easy. For two main reasons:
the function and the definition work in the opposite directions,
the definition does not have an optimal expression for reasoning.
However, one can write a lemma function to solve the problem:
#include <stdbool.h>
#define SIZE 1000
bool data[SIZE] ;
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : ((data[begin]==true) ? count(begin+1, end)+1 : count(begin+1, end));
*/
/*# ghost
/# requires begin < end ;
assigns \nothing ;
ensures count(begin, end) == ((data[end-1]==true) ? count(begin, end-1)+1 : count(begin, end-1));
#/
void lemma(bool* d, int begin, int end){
/# loop invariant begin <= i < end ;
loop invariant count(i, end) == ((data[end-1]==true) ? count(i, end-1)+1 : count(i, end-1));
loop assigns i ;
loop variant i - begin ;
#/
for(int i = end-1 ; i > begin ; i--);
}
*/
/*#
requires SIZE > begin >= 0;
requires SIZE >= end >= 0;
requires begin <= end;
assigns \nothing;
ensures \result == count(begin, end);
*/
unsigned int occurrences_of(int begin, int end)
{
unsigned int result = 0;
/*#
loop invariant i_bound: begin <= i <= end;
loop invariant result_bound: 0 <= result <= i-begin;
loop invariant result_val: result == count(begin, i);
loop assigns i, result;
loop variant end-i;
*/
for (unsigned int i = begin; i < end; ++i){
result += (data[i] == true) ? 1 : 0;
//# ghost lemma(data, begin, i+1);
}
return result;
}
I'd suggest to use the following definition:
/*#
logic integer count(integer begin, integer end)=
begin >= end ? 0 : ((data[end-1]==true) ? 1 : 0) + count(begin, end-1);
*/
It works in the same direction as the function and avoids the duplication of the term count(begin, end-1) which makes reasoning easier.
I would like to generate in an efficient way a list of integers (preferably ordered)
with the following defining properties:
All integers have the same number of bit set N.
All integers have the same sum of bit indices K.
To be definite, for an integer I
its binary representation is:
$I=\sum_{j=0}^M c_j 2^j$ where $c_j=0$ or $1$
The number of bit sets is:
$N(I)=\sum_{j=0}^M c_j$
The sum of bit indices is:
$K(I)=\sum_{j=0}^M j c_j$
I have an inefficient way to generate the list as follows:
make a do/for loop over integers incrementing by use
of a "snoob" function - smallest next integer with same number of bit set
and at each increment checking if it has the correct value of K
this is grossly inefficient because in general starting from an integer
with the correct N and K value the snoob integer from I does not have the correct K and one has to make many snoob calculations to get the next integer
with both N and K equal to the chosen values.
Using snoob gives an ordered list which is handy for dichotomic search but
not absolutely compulsory.
Counting the number of elements in this list is easily done by recursion
when viewed as a partition numner counting. here is a recursive function in fortran 90 doing that job:
=======================================================================
recursive function BoundedPartitionNumberQ(N, M, D) result (res)
implicit none
! number of partitions of N into M distinct integers, bounded by D
! appropriate for Fermi counting rules
integer(8) :: N, M, D, Nmin
integer(8) :: res
Nmin = M*(M+1)/2 ! the Fermi sea
if(N < Nmin) then
res = 0
else if((N == Nmin) .and. (D >= M)) then
res = 1
else if(D < M) then
res = 0
else if(D == M) then
if(N == Nmin) then
res = 1
else
res = 0
endif
else if(M == 0) then
res = 0
else
res = BoundedPartitionNumberQ(N-M,M-1,D-1)+BoundedPartitionNumberQ(N-M,M,D-1)
endif
end function BoundedPartitionNumberQ
========================================================================================
My present solution is inefficient when I want to generate lists with several $10^7$
elements. Ultimately I want to stay within the realm of C/C++/Fortran and reach lists of lengths
up to a few $10^9$
my present f90 code is the following:
program test
implicit none
integer(8) :: Nparticles
integer(8) :: Nmax, TmpL, CheckL, Nphi
integer(8) :: i, k, counter
integer(8) :: NextOne
Nphi = 31 ! word size is Nphi+1
Nparticles = 16 ! number of bit set
print*,Nparticles,Nphi
Nmax = ishft(1_8, Nphi + 1) - ishft(1_8, Nphi + 1 - Nparticles)
i = ishft(1, Nparticles) - 1
counter = 0
! integer CheckL is the sum of bit indices
CheckL = Nparticles*Nphi/2 ! the value of the sum giving the largest list
do while(i .le. Nmax) ! we increment the integer
TmpL = 0
do k=0,Nphi
if (btest(i,k)) TmpL = TmpL + k
end do
if (TmpL == CheckL) then ! we check whether the sum of bit indices is OK
counter = counter + 1
end if
i = NextOne(i) ! a version of "snoob" described below
end do
print*,counter
end program
!==========================================================================
function NextOne (state)
implicit none
integer(8) :: bit
integer(8) :: counter
integer(8) :: NextOne,state,pstate
bit = 1
counter = -1
! find first one bit
do while (iand(bit,state) == 0)
bit = ishft(bit,1)
end do
! find next zero bit
do while (iand(bit,state) /= 0)
counter = counter + 1
bit = ishft(bit,1)
end do
if (bit == 0) then
print*,'overflow in NextOne'
NextOne = not(0)
else
state = iand(state,not(bit-1)) ! clear lower bits i &= (~(bit-1));
pstate = ishft(1_8,counter)-1 ! needed by IBM/Zahir compiler
! state = ior(state,ior(bit,ishft(1,counter)-1)) ! short version OK with gcc
state = ior(state,ior(bit,pstate))
NextOne = state
end if
end function NextOne
Since you mentioned C/C++/Fortran, I've tried to keep this relatively language agnostic/easily transferable but have also included faster builtins alternatives where applicable.
All integers have the same number of bit set N
Then we can also say, all valid integers will be permutations of N set bits.
First, we must generate the initial/min permutation:
uint32_t firstPermutation(uint32_t n){
// Fill the first n bits (on the right)
return (1 << n) -1;
}
Next, we must set the final/max permutation - indicating the 'stop point':
uint32_t lastPermutation(uint32_t n){
// Fill the last n bits (on the left)
return (0xFFFFFFFF >> n) ^ 0xFFFFFFFF;
}
Finally, we need a way to get the next permutation.
uint32_t nextPermutation(uint32_t n){
uint32_t t = (n | (n - 1)) + 1;
return t | ((((t & -t) / (n & -n)) >> 1) - 1);
}
// or with builtins:
uint32_t nextPermutation(uint32_t &p){
uint32_t t = (p | (p - 1));
return (t + 1) | (((~t & -~t) - 1) >> (__builtin_ctz(p) + 1));
}
All integers have the same sum of bit indices K
Assuming these are integers (32bit), you can use this DeBruijn sequence to quickly identify the index of the first set bit - fsb.
Similar sequences exist for other types/bitcounts, for example this one could be adapted for use.
By stripping the current fsb, we can apply the aforementioned technique to identify index of the next fsb, and so on.
int sumIndices(uint32_t n){
const int MultiplyDeBruijnBitPosition[32] = {
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
int sum = 0;
// Get fsb idx
do sum += MultiplyDeBruijnBitPosition[((uint32_t)((n & -n) * 0x077CB531U)) >> 27];
// strip fsb
while (n &= n-1);
return sum;
}
// or with builtin
int sumIndices(uint32_t n){
int sum = 0;
do sum += __builtin_ctz(n);
while (n &= n-1);
return sum;
}
Finally, we can iterate over each permutation, checking if the sum of all indices matches the specified K value.
p = firstPermutation(n);
lp = lastPermutation(n);
do {
p = nextPermutation(p);
if (sumIndices(p) == k){
std::cout << "p:" << p << std::endl;
}
} while(p != lp);
You could easily change the 'handler' code to do something similar starting at a given integer - using it's N & K values.
A basic recursive implementation could be:
void listIntegersWithWeight(int currentBitCount, int currentWeight, uint32_t pattern, int index, int n, int k, std::vector<uint32_t> &res)
{
if (currentBitCount > n ||
currentWeight > k)
return;
if (index < 0)
{
if (currentBitCount == n && currentWeight == k)
res.push_back(pattern);
}
else
{
listIntegersWithWeight(currentBitCount, currentWeight, pattern, index - 1, n, k, res);
listIntegersWithWeight(currentBitCount + 1, currentWeight + index, pattern | (1u << index), index - 1, n, k, res);
}
}
That is not my suggestion, just the starting point. On my PC, for n = 16, k = 248, both this version and the iterative version take almost (but not quite) 9 seconds. Almost exactly the same amount of time, but that's just a coincidence. More pruning can be done:
currentBitCount + index + 1 < n if the number of set bits cannot reach n with the number of unfilled positions that are left, continuing is pointless.
currentWeight + (index * (index + 1) / 2) < k if the sum of positions cannot reach k, continuing is pointless.
Together:
void listIntegersWithWeight(int currentBitCount, int currentWeight, uint32_t pattern, int index, int n, int k, std::vector<uint32_t> &res)
{
if (currentBitCount > n ||
currentWeight > k ||
currentBitCount + index + 1 < n ||
currentWeight + (index * (index + 1) / 2) < k)
return;
if (index < 0)
{
if (currentBitCount == n && currentWeight == k)
res.push_back(pattern);
}
else
{
listIntegersWithWeight(currentBitCount, currentWeight, pattern, index - 1, n, k, res);
listIntegersWithWeight(currentBitCount + 1, currentWeight + index, pattern | (1u << index), index - 1, n, k, res);
}
}
On my PC with the same parameters, this only takes half a second. It can probably be improved further.
How can I write this algorithm using iteration?
function generate(num1:byval)
if num1 > 10 then
return 10
else
return num1 + (generate(num1 + 1) DIV 2)
endif
endfunction
So it's not straight forward so I start by doing some grunt work:
n result
11.. 10
10 10
9 9 + 10/2
8 8 + (9 + 10/2)/2
7 7 + (8 + (9 + 10/2)/2)/2
This looks like a pattern.. While the recursive version started on the input and went upwards it's easy to see that by starting at 10 and going downwards one can simply update the accumulator by halving the value and adding the current value.
This can easily be implemented using a helper:
procedure generate(num : integer) : integer
begin
generate := generateHelper(10, num, 0)
end
procedure generateHelper(cur : integer, num: integer, acc : integer) : integer
begin
if cur = num then
generateHelper := cur + acc/2;
else
generateHelper := generateHelper(cur - 1, num, acc/2 + cur);
end
Or by using a loop:
procedure generate(num : integer) : integer
var cur, acc : integer;
begin
for cur := 10 downto cur do
acc := acc / 2 + cur;
generate := acc;
end
If you work out some values for the function…
f(10) = 10
f(9) = 9+f(10)/2 = 9+10/2 = 14
f(8) = 8+f(9)/2 = 8+14/2 = 15
…
You will get a sense that you could repeatedly apply the same formula to a value in a loop. You see if you start from 10, you divide by 2 and add 9, then divide by 2 and add 8, and keep going until you reach the number given to the function. That would look something like this, e.g. in JavaScript:
function generate(n) {
let x = 10;
for(let i = 10; i > n; i--) {
x = i - 1 + x / 2;
}
return x;
}
Given a bag with a maximum of 100 chips,each chip has its value written over it.
Determine the most fair division between two persons. This means that the difference between the amount each person obtains should be minimized. The value of a chips varies from 1 to 1000.
Input: The number of coins m, and the value of each coin.
Output: Minimal positive difference between the amount the two persons obtain when they divide the chips from the corresponding bag.
I am finding it difficult to form a DP solution for it. Please help me.
Initially I had to tried it as a Non DP solution.Actually I havent thought of solving it using DP. I simply sorted the value array. And assigned the largest value to one of the person, and incrementally assigned the other values to one of the two depending upon which creates minimum difference. But that solution actually didnt work.
I am posting my solution here :
bool myfunction(int i, int j)
{
return(i >= j) ;
}
int main()
{
int T, m, sum1, sum2, temp_sum1, temp_sum2,i ;
cin >> T ;
while(T--)
{
cin >> m ;
sum1 = 0 ; sum2 = 0 ; temp_sum1 = 0 ; temp_sum2 = 0 ;
vector<int> arr(m) ;
for(i=0 ; i < m ; i++)
{
cin>>arr[i] ;
}
if(m==1 )
{
if(arr[0]%2==0)
cout<<0<<endl ;
else
cout<<1<<endl ;
}
else {
sort(arr.begin(), arr.end(), myfunction) ;
// vector<int> s1 ;
// vector<int> s2 ;
for(i=0 ; i < m ; i++)
{
temp_sum1 = sum1 + arr[i] ;
temp_sum2 = sum2 + arr[i] ;
if(abs(temp_sum1 - sum2) <= abs(temp_sum2 -sum1))
{
sum1 = sum1 + arr[i] ;
}
else
{
sum2 = sum2 + arr[i] ;
}
temp_sum1 = 0 ;
temp_sum2 = 0 ;
}
cout<<abs(sum1 -sum2)<<endl ;
}
}
return 0 ;
}
what i understand from your question is you want to divide chips in two persons so as to minimize the difference between sum of numbers written on those.
If understanding is correct, then potentially you can follow below approach to arrive at solution.
Sort the values array i.e. int values[100]
Start adding elements from both ends of array in for loop i.e. for(i=0; j=values.length;i<j;i++,j--)
Odd numbered iteration sum belongs to one person & even numbered sum to other person
run the loop till i < j
now, the difference between two sums obtained in odd & even iterations should be minimum as array was sorted earlier.
If my understanding of the question is correct, then this solution should resolve your problem.
Reflect as appropriate.
Thanks
Ravindra
So I'm trying to permute all possible n digit long numbers out of x long array/set of elements. I've come up with a code that does that, however the digits are the same, how do I prevent that from happening. Here's my come(Pascal):
program Noname10;
var stop : boolean;
A : array[1..100] of integer;
function check( n : integer ) : boolean;
begin
if n = 343 // sets the limit when to stop.
then check := true
else check := false;
end;
procedure permute(p,result : integer);
var i : integer;
begin
if not stop
then if p = 0 then
begin
WriteLn(result);
if check(result)
then stop := true
end
else for i := 1 to 9 do
begin
permute(p - 1, 10*result+i);
end;
end;
begin
stop := false;
permute(3,0);
readln;
end.
Here is the code in Prolog
permutate(As,[B|Cs]) :- select(B, As, Bs), permutate(Bs, Cs).
select(A, [A|As], As).
select(A, [B|Bs], [B|Cs]) :- select(A, Bs, Cs).
?- permutate([a,b,c], P).
Pascal is much harder.
Here is an usefull algorithm, you might want to use. But it is not tested, so you have to debug it yourself. So you have to know how the algorithm works.
The Bell Permutation algorithm: http://programminggeeks.com/bell-algorithm-for-permutation/
procedure permutate(var numbers: array [1..100] of integer; size: integer;
var pos, dir: integer)
begin
if pos >= size then
begin
dir = -1 * dir;
swap(numbers, 1, 2);
end
else if pos < 1 then
begin
dir = -1 * dir;
swap(numbers, size-1, size);
end
else
begin
swap(numbers, pos, pos+1);
end;
pos = pos + dir;
end;
begin
var a, b: integer;
a = 1; b = 1;
while true do
begin
permutate(A, 5, a, b);
printArray(A, 5);
end;
end.