Why asterisk is overloaded for types? - operator-overloading

I still don't understand the motivation.
Why did they made two different operators (* and *.) for multiplication of integers and floats respectively as if they afraid of overloading, but at the same time they used * to denote Cartesian product of types?
type a = int * int ;;
Why suddenly they became so brave? Why not to write
type a = int *.. int ;;
or something?
Is there some relation, which makes Cartesian product closer to integer product and more far from float product?

It's not overloaded, on the right hand-side of type t = you are defining another kind of concept, you are defining a type, not a value.
In ML-like languages you can see two distinct language:
The language for types that allows you to define types (a specification of the structure of your values).
The language for values that allows you to define values (actual values corresponding to a type, functions are also values). That's what gets evaluated.
Since the domain of the two language are really separate there's no theoretical problem/ambiguity in reusing similar syntactic construct in each language and hence has absolutely nothing to do with overloading.

In mathematics, you note cartesian product using the multiplication character. So it is logic to note it the same way in OCaml...

Related

in coq how to assume equality of two natural numbers

I want to use this definition to assume that certain equalities on the members of set R hold:
Definition wiring: Prop
(globalHasVoltage -> (voltageOf voltageIn) = vcc)
/\
(globalHasGround -> (
(voltageOf control) = zero
/\
(voltageOf ground) = zero
)
)
.
It seems coq distinguishes between Prop and bool, what are the differences, and how may i solve that issue?
Also If this definition implies some other definition (per say lets call it toBeEvaluated) and assuming that conversion between bool and prop can be done could this
Definition toBeEvaluated: Prop := (voltageOf voltageIn) = vcc.
be proven using unwraps and tauto. (In particular will it work with functions which have exact definitions)
The difference between Prop and bool is that definitions in Prop might be undecidable, while definitions in bool can always be computed (unless you use axioms). Many number types have bool and Prop equality operators, but R doesn't because equality in R is in principle undecidable, so one can't write an equality function for R which results in a bool. Imagine e.g. the equality of different infinite series which sum up to pi - one can't design a general algorithm which decides if two series result in pi or not. Electronics uses functions like sin which rely on such infinite series.
A few options / thoughts:
R is not a very appropriate type for signal levels. E.g. voltage levels like GND or VCC are not mathematically equal everywhere. You could e.g. work with ranges in Q to express signal levels.
Another appropriate type might be floating point numbers, which are supported by Coq (meanwhile also natively). Have a look at the coq-flocq package. For floating point numbers equality is decidable, but they won't be able to represent a voltage like 1.8V exactly.
Another option is to have an inductive type which has a few well known signal levels (GND, VCC, ...) but also a constructor for arbitrary R (either classic or constructive). At least for the well known levels equality would be decidable then, but not for the arbitrary levels.
Even though = is not decidable in R, you can usually proof equality of R expressions, e.g. using the ring or field tactic. But you can't prove automatically that say sin(pi/4)=cos(pi/4). Well of cause one can automate this as well, but such automation always will have limits. But this means that your equalities always need to be proven with tactics and can't be just computed.

Effective ways to represent logical expression

I am writing a console program to represent logical expressions( something likes AB'C + A'C) so that I can be simplify( optimize) the expressions and evaluate their values. I tried to use string to represent an expression, but in this way, I can only evaluate its value base on input values, but optimize an expression that represented as string is very difficult( with me), Example, ABC + AB can be AB because ABC+AB = AB(C+1) = AB. I have also think another way it is using vector of vector of literal. Example, AB'C + AB + BC will be represent as below figure:
Explaining: Each column is represent for each term, in above example. The first column represents for AB'C, the second one represents for AB and the third one represents for BC'.
I think it is a good way to present logical expression but I still can not find a way to optimize an expression that repression by this way. I also googled but I did not find sample project for the problem.
In short, I hope someone suggest to me a way to represent, evaluate and optimize an logical expression easier. Thank in advance!
How to represent, evaluate and optimize a logical expression?
To represent this you need to use an expression tree and since you are using only logic operators that are binary operators you want to use a binary expression tree or more specifically this.
To simplify the tree you use the laws of Boolean algebra.
If all of the values are bound, then through the process of simplification the tree will simplify to a root node with either true or false.
For some example code I checked Rosetta Code but they had no task for evaluating Boolean expressions. The closest task is arithmetic evaluation.

Scala constraint based types and literals

I was thinking whether it would be possible in Scala to define a type like NegativeNumber. This type would represent a negative number and it would be checked by the compiler similarly to Ints, Strings etc.
val x: NegativeNumber = -34
val y: NegativeNumber = 34 // should not compile
Likewise:
val s: ContainsHello = "hello world"
val s: ContainsHello = "foo bar" // this should not compile either
I could use these types just like other types, eg:
def myFunc(x: ContainsHello): Unit = println(s"$x contains hello")
These constrained types could be backed by casual types (Int, String).
Is it possible to implement these types (maybe with macros)?
How about custom literals?
val neg = -34n //neg is of type NegativeNumber because of the suffix
val pos = 34n // compile error
Unfortunately, no this isn't something you could easily check at compile time. Well - at least not if you aren't restricting the operations on your type. If your goal is simply to check that a number literal is non-zero, you could easily write a macro that checks this property. However, I do not see any benefit in proving that a negative literal is indeed negative.
The problem isn't a limitation of Scala - which has a very strong type system - but the fact that (in a reasonably complex program) you can't statically know every possible state. You can however try to overapproximate the set of all possible states.
Let us consider the example of introducing a type NegativeNumber that only ever represents a negative number. For simplicity, we define only one operation: plus.
Say you would only allow addition of multiple NegativeNumber, then, the type system could be used to guarantee that each NegativeNumber is indeed a negative number. But this seems really restrictive, so a useful example would certainly allow us to add at least a NegativeNumber and a general Int.
What if you had an expression val z: NegativeNumber = plus(x, y) where you don't know the value of x and y statically (maybe they are returned by a function). How do you know (statically) that z is indead a negative number?
An approach to solve the problem would be to introduce Abstract Interpretation which must be run on a representation of your program (Source Code, Abstract Syntax Tree, ...).
For example, you could define a Lattice on the numbers with the following elements:
Top: all numbers
+: all positive numbers
0: the number 0
-: all negative numbers
Bottom: not a number - only introduced that each pair of elements has a greatest lower bound
with the ordering Top > (+, 0, -) > Bottom.
Then you'd need to define semantics for your operations. Taking the commutative method plus from our example:
plus(Bottom, something) is always Bottom, as you cannot calculate something using invalid numbers
plus(Top, x), x != Bottom is always Top, because adding an arbitrary number to any number is always an arbitrary number
plus(+, +) is +, because adding two positive numbers will always yield a positive number
plus(-, -) is -, because adding two negative numbers will always yield a negative number
plus(0, x), x != Bottom is x, because 0 is the identity of the addition.
The problem is that
plus - + will be Top, because you don't know if it's a positive or negative number.
So to be statically safe, you'd have to take the conservative approach and disallow such an operation.
There are more sophisticated numerical domains but ultimately, they all suffer from the same problem: They represent an overapproximation to the actual program state.
I'd say the problem is similar to integer overflow/underflow: Generally, you don't know statically whether an operation exhibits an overflow - you only know this at runtime.
It could be possible if SIP-23 was implemented, using implicit parameters as a form of refinement types. However, it would be of questionable value though as the Scala compiler and type system is not really not well equipped for proving interesting things about for example integers. For that it would be much nicer to use a language with dependent types (Idris etc.) or refinement types checked by an SMT solver (LiquidHaskell etc.).

OpenCL select() function with double

I'm porting some complex engineering code to OpenCL and have run into a problem with the select() ternary function with doubles. I'm just using scalars for now so I could use the simple C ternary operator ()?: but I plan to move to vector types soon.
My problem is that select with doubles requires a (long) type as the comparison but the scalar relational functions (e.g., isgreater) only return (int) for doubles. The prototypes for these functions are ...
int isgreater (double a, double b);
longn isgreater (doublen a, doublen b);
double select (double a, double b, long cmp);
doublen select (doublen a, doublen b, longn cmp);
I can get the scalar code to compile/run in scalar mode only if I cast the results of isgreater() as a long since select requires the element types to by the same size.
double hi = ...;
double lo = ...;
double res = select (lo, hi, (long)isgreater(T, T_cutoff));
Otherwise, I get a compiler error since select is ambiguous. There seems to be a mismatch in the specification regarding the relational mask types for scalar and vector doubles.
Q1: Is this an oversight in the specification or a bug in the implementation? Both the Intel and AMD OpenCL compilers fail for builds on the CPU so I'm guessing is the former.
Q2: OpenCL scalar relational functions return 0/1 and vector relational functions return 0/-1 (that is, all bits set). The (int)->(long) conversion appears to be consistent with this requirement but not (int)->(ulong), right? Is the (int)->(long) conversion costly?
Q3: When (if) I switch to vector doubles, will the compiler toss out the unnecessary explicit conversion? I want to retain both scalar and vector types so I can target CUDA GPUs and SIMD devices (MIC, CPUs) w/o having to keep two massive code sets.
Thanks for any advice here.
Q1:
I'd say that not implicitly converting the result of isgreater into long is an oversight in the specification.
In the single element case select should work exactly like ternary operator. That's also the reason isgreater returns 1 in scalar case. Basically isgreater should work exactly like > does when scalar operators are used.
In the vectorized case select looks at the MSB, which is the reason isgreater returns -1 (All bits 1 so MSB is naturally 1 too).
Q2: Int long conversion shouldn't be costly at all. At most it just requires 1 additional instruction.
Q3:
It does not.
This issue annoyingly prevents one from making a code that vectorizes from 1 to n elements, it requires special handling for the scalar case.

Where can I find a cheat sheet for hungarian notation?

I'm working on a legacy COM C++ project that makes use of system hungarian notation. Because it's maintenance of legacy code, the convention is to code in the original style it was written in - our newer code isn't coded this way. So I'm not interested in changing that standard or having a a discussion of our past sins =)
Is there an online cheat-sheet available out there for systems hungarian notation?
The best I can find thus far is a pre stack-overflow discussion post, but it doesn't quite have everything I've needed in the past. Does anyone have any other links?
(making this community wiki in the hope this becomes a self populating list)
If this is for a legacy COM project, you'll probably want to follow Microsoft's Hungarian Notation specifications, which are documented on MSDN.
Note that this is Apps Hungarian, i.e. the "good" kind of Hungarian Notation. Systems Hungarian is the "bad" kind, where names are prefixed with their compiler types, e.g. i for int.
Tables from the MSDN article
Table 1. Some examples for procedure names
Name Description
InitSy Takes an sy as its argument and initializes it.
OpenFn fn is the argument. The procedure will "open" the fn. No value is returned.
FcFromBnRn Returns the fc corresponding to the bn,rn pair given. (The names cannot tell us what the types sy, fn, fc, and so on, are.)
The following is a list of standard type constructions. (X and Y stand for arbitrary tags. According to standard punctuation, the actual tags are lowercase.)
Table 2. Standard type constructions
pX Pointer to X.
dX Difference between two instances of type X. X + dX is of type X.
cX Count of instances of type X.
mpXY An array of Ys indexed by X. Read as "map from X to Y."
rgX An array of Xs. Read as "range X." The indices of the array are called:
iX index of the array rgX.
dnX (rare) An array indexed by type X. The elements of the array are called:
eX (rare) Element of the array dnX.
grpX A group of Xs stored one after another in storage. Used when the X elements are of variable size and standard array indexing would not apply. Elements of the group must be referenced by means other then direct indexing. A storage allocation zone, for example, is a grp of blocks.
bX Relative offset to a type X. This is used for field displacements in a data structure with variable size fields. The offset may be given in terms of bytes or words, depending on the base pointer from which the offset is measured.
cbX Size of instances of X in bytes.
cwX Size of instances of X in words.
The following are standard qualifiers. (The letter X stands for any type tag. Actual type tags are in lowercase.)
Table 3. Standard qualifiers
XFirst The first element in an ordered set (interval) of X values.
XLast The last element in an ordered set of X values. XLast is the upper limit of a closed interval, hence the loop continuation condition should be: X <= XLast.
XLim The strict upper limit of an ordered set of X values. Loop continuation should be: X < XLim.
XMax Strict upper limit for all X values (excepting Max, Mac, and Nil) for all other X: X < XMax. If X values start with X=0, XMax is equal to the number of different X values. The allocated length of a dnx vector, for example, will be typically XMax.
XMac The current (as opposed to constant or allocated) upper limit for all X values. If X values start with 0, XMac is the current number of X values. To iterate through a dnx array, for example:
for x=0 step 1 to xMac-1 do ... dnx[x] ...
or
for ix=0 step 1 to ixMac-1 do ... rgx[ix] ...
XNil A distinguished Nil value of type X. The value may or may not be 0 or -1.
XT Temporary X. An easy way to qualify the second quantity of a given type in a scope.
Table 4. Some common primitive types
f Flag (Boolean, logical). If qualifier is used, it should describe the true state of the flag. Exception: the constants fTrue and fFalse.
w Word with arbitrary contents.
ch Character, usually in ASCII text.
b Byte, not necessarily holding a coded character, more akin to w. Distinguished from the b constructor by the capital letter of the qualifier in immediately following.
sz Pointer to first character of a zero terminated string.
st Pointer to a string. First byte is the count of characters cch.
h pp (in heap).
Here's one for 'Systems Hungarian', which in my experience was the more commonly used (and less useful):
http://web.mst.edu/~cpp/common/hungarian.html
But how universally followed this is, I have no idea.
The other form of Hungarian Notation is "Apps Hungarian", which apparently is Simonyi's original intent (the use of the variable was encoded rather than the type). See http://en.wikipedia.org/wiki/Hungarian_notation for some details.
Because this is a legacy project, your software department manager should have a copy of the style guide for whatever version of Hungarian Notation the original programmers used. (I'm assuming that the original programmers have long since fled to more enlightened workplaces.)
You really should reconsider your use of Hungarian notation. It was originally a patch for the lack of strong typing (and compiler type-checking) in C. Modern compilers enforce type-correctness, making Hungarian notation redundant at best, and erroneous otherwise.
There doesn't seem to be any one exhaustive resource for looking up Hungarian Notation prefixes, probably because a lot of it varied from code base to code base. There, of course, were a lot of very commonly used ones.
The best list I could find was here
The rest cover the commonly used conventions such as this entry
MSDN's enty on Hungarian Notation is here
and a couple of short papers on the subject (overlapping each other perhaps) here and here
Your best bet would be to see how the variables are used and that (may) help you figure out the definition of the prefixes (though in practice the naming rarey reflected the use of the variable, sadly).
You might be able to piece together some semblance of notation from those various links.
Just to be complete(!) how about Hungarian Object Notation for Visual Basic from Microsoft Support no less.