What does the below code do? How can I write this OCL expression when there is one element instead of elements?
In other words, I don't understand which elements does the code collect?
Since "collect" is used when we have more than one element, if I have one element (instead of elements), what changes occure to "-> collect (s|thisModule.CreateMatchClass(s))" part of that expression?
s.source.elements -> collect (s|thisModule.CreateAnyMatchClass(s))
Your OCL expression simply 'create' elements (regarding the name of the thismodule function) from the elements that are in s.source. The created elements are then returned as a Collection:
s.source.elements return (supposedly) a Collection (could be a Set/Sequence...) by navigating from s
collect(...) gathers the results of its parameter expression
How to change the expression if the relation elements is not 0..* anymore but 0..1 or 1..1?
Indeed, collect(...) works with collections, but -> is also an implicit converter to a Set. The page 15 of the OCL specification states:
The "->" navigation shorthand performs an implicit set conversion of an object.
anObject->union(aSet) is a shorthand for anObject.oclAsSet()->union(aSet)
It means that in the case element (I removed the final 's') is a "single" relationship and s.source.element returns a single element, the call s.source.element->... is equivalent to s.source.element.oclAsSet()->.... In your case, whether elements is many or not, the expression is still the same:
s.source.elements -> collect (s|thisModule.CreateAnyMatchClass(s))
This expression will work in both cases.
If you really don't want the collect and if you have your elements relationship which is single, you can write this also:
thisModule.createAnyMatchClass(s.source.elements)
Related
I'm trying to create a list of unique by appending to a list, but I'm getting this error.
Error: This expression has type 'a list
but an expression was expected of type unit
in_list is a boolean function that checks whether the value is in the list.
if(in_list x seen_list) then print_string("Already found") else seen_list#x in
List.iter uniq check_list;;
It seems like there must be some small syntactic error I need to fix for the append function. Suggestions?
TL;DR: Lists are immutable in OCaml
According to your code, you seem to believe that lists are mutable in OCaml, and they are not. Hence seen_list#x compute a new list but does not change seen_list.
You could change your code to
let uniq seen_list x =
if in_list x seen_list then
(Printf.printf: "uniq: %d: Already seen.\n" x; seen_list)
else x :: seen_list
in
List.fold_left uniq [] check_list
The uniq function maps a list of integers to a list of integers without repetitions, logging the entries it skips.
This code is obviously intended to be learning material, I guess, nevertheless you should be aware that it most likely implements a Shlemiel the painter's algorithm.
This is a type error, not a syntactic error.
An OCaml function must always return a result of the same type. Right now, when the item is in the list your function tries to return a different type than if the item is not in the list.
Specifically, when the item is already there your function calls print_string, which returns (). This is called unit, and is a placeholder representing no interesting value. When the item isn't already there, your function returns a value of type 'a list. Almost certainly what you need to do is to return a list in all cases.
It's hard to say more without seeing more of your code, but the most usual way to handle this situation is to return the old list when the item is already there and a new, longer list when the item isn't already there.
Update
There are many things to fix in this code, but that's the point of the exercise I assume.
Your next problem seems to be that List.iter is an imperative function, i.e., it wants to do something rather than produce a result. Hence the function that it iterates over the list should return unit (described above). You're using the function uniq instead, which returns a list.
If you want to use a higher-order function like List.iter, which is excellent OCaml style, you will need to use a fold (List.fold_left or List.fold_right), whose purpose is to accumulate a result.
%% Function even_print(List),takes a list and returns a list of only even numbers. Function even_odd(X), takes an integer and tells if it is even or odd.
even_print(List) ->
[X||X<-List, even<-even_odd(X)].
I don't understand why I get this error:
3> seq_erlang:even_print([2,3,4]).
** exception error: no function clause matching
seq_erlang:'-even_print2/1-lc$^1/1-1-'(even) (seq_erlang.erl, line 154)
Just to comment, I have already implemented another function that prints even numbers just fine (so please don't comment with other implementations). I need help with this one only.
That should be even == even_odd(X) instead of using <-. A list comprehension has two types of "clauses": those that map over a list with <-, and those that filter out undesired combinations using a guard or boolean expression that doesn't contain <-.
(And a third one: extract bytes from a binary using <=; but that one is more rarely used.)
For an assignment, I have to create a type inference relation. here's the approach I used
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(tuples(T),tuples(Z)),type(X,Y).
I have already defined the type relation for all possible terms required for my assignment where y is the type of X in type(X,Y). For defining types of n-tuples, I used the approach similiar to the one used for appending lists.
But prolog always returns false when I ask
?-type(tuples([3,str]),Z)
or even
?-type(tuples([3,str]),tuples(Z))
or
?-type(tuples([3,str,4,abc,5,6]),Z)
i.e a list of length n, the answer returned is false.
Nothing changed even when I revered the sub-rules in the last rule.
tuples([]).
tuples(_|_).
type(tuples([]),tuples([])).
type(tuples(X|T),tuples(Y|Z)) :- type(X,Y),type(tuples(T),tuples(Z)).
I am not asking for alternative approaches to type of tuples to help me in my assignment but I can't figure out why this approach is not working.
It looks like your definition of a tuple is a List with length 2.
This rule does not check for that:
tuples(_|_).
What you probably want is this:
tuples([_,_]).
If you want it to check for any length list, use:
tuples([_|_]).
In the latter rule, the first wildcard represents the first item in the list (the head) and the second wildcard represents the rest of the list (the tail).
I simply want to pass a list of integers to a function written in C++. I've set up the template (.tm) file and all, and I can successfully call a test function whith scalar arguments. Calling the function with the list argument behaves as though the function was not defined at all. I suspect that the argument types don't match.
In the documentation for templates (http://reference.wolfram.com/mathematica/ref/file/file.tm.html) the datatype for lists is something like "Int32List". When I use that, my C++ function must contain an extra long parameter for the list length. The only example code which uses a list is "sumalist.tm". This example uses IntegerList (a type which doesn't appear in the doku).
When I use Int32List, the mprep result requires a function with an extra integer argument (not long as written in the doku). When I use the undocumented IntegerList type, the extra argument is of type long.
During my experiments with scalar types, I had a similar problem - a c++ function was called properly when using "Integer" in the tm-file, and not recognized with "Integer32".
The "sumalist.tm" example also uses a strange Pattern (list:{___Integer}) about which I didn't find any documentation. I'd also like to understand what the Evaluate line means (I suspect that it's used make the function callable without the curly braces around the list).
So who know which datatypes are really appropriate to call a c++ function with a list - maybe also with reals... ?
The mapping of MathLink data types (e.g., Integer32, Integer32List, ...) to C/C++ types is described on the MathLink template file documentation page.
The page no longer documents the old interface types Integer, Real, IntegerList and RealList. These should no longer be used, because the mapping of these types depends on C types whose bit length is platform and compiler dependent (e.g., long). Use the corresponding new type with explicit bit length instead (i.e., Integer32 or Integer64 instead of Integer). The old interface types are still documented in the somewhat dated MathLink reference guide.
The following talk slides contain a simple MathLink example that shows how to implement a MathLink function that adds a scalar value to a vector of reals. This may serve as a starting point.
I don't know much about MathLink, but I can explain the pattern, list:{___Integer}.
The colon is just the general form for a named pattern, that is symbol:pattern just says that the object referred to by symbol has to match pattern. Indeed, pattern like a_Integer or b__List are really just short forms for a:_Integer and b:__List.
So what we are left with interpreting is {___Integer}. This is a pattern matching a list of arbitrary many (including zero) integers. It works as follows:
{Pattern} is the Pattern for a list whose contents matches Pattern
___Integer is the Pattern for a sequence of zero or more Integers.
I created a set of programs to calculate the area under a graph using various methods of approximation (midpoint, trapezoidal, simpson) for my Calculus class.
Here is an example of one of my programs (midpoint):
Prompt A,B,N
(A-B)/N->D
Input "Y1=", Y1
0->X
0->E
For(X,A+D/2,b-D/2,D)
Y1(x)+E->E
End
Disp E*D
Instead of applying these approximation rules to a function (Y1), I would like to apply them to a list of data (L1). How do I iterate through a list? I would need to be able to get the last index in the list in order for a "For Loop" to be any good. I can't do anything like L1.length like I would do in Java.
You can obtain the length of the list using dim(). That can be found in 2nd->LIST->OPS->dim(. Just make sure that you use a list variable otherwise dim() will complain about the type. You could then index into the list with a subscript.
e.g.,
{1, 2, 3, 4} -> L1
For (X, 1, dim(L1), 1)
Disp L1(X)
End
The for loop is the simplest way to iterate over a list in TI-Basic, as it is in many languages. Jeff Mercado already covered that, so I'll mention a few techniques that are powerful tools in specialized situation.
Mapping over lists
TI-Basic supports simple mapping operation over lists that have the same effect as a map function in any other language. TI-Basic support for this extends to most basic arithmetic function, and selection of other functions.
The syntax could not be simpler. If you want to add some number X to every element in some list L1 you type X+L1→L1.
seq(
Most for loops over a lists in TI-Basic can be replaced by cleverly constructed seq( command that will outperform the for loop in time and memory. The exceptions to this rule are loops that contain I/O or storing variables.
The syntax for this command can be quite confusing, so I recommend reading over this documentation before using it. In case that link dies, here's the most relevant information.
Command Summary
Creates a list by evaluating a formula with one variable taking on a
range of values, optionally skipping by a specified step.
Command Syntax
seq(formula, variable, start-value, end-value [, step])
Menu Location
While editing a program, press:
2nd LIST to enter the LIST menu RIGHT to enter the OPS submenu 5 to
choose seq(, or use arrows.
Calculator Compatibility
TI-83/84/+/SE
Token Size
1 byte
The documentation should do a good job explaining the syntax for seq(, so I'll just provide a sample use case.
If you want the square of every number between 1 and 100 you could do this
For Loop
DelVar L1100→dim(L1
for(A,1,100
A²→L1(A
End
or, this
seq
seq(A²,A,1,100→L1
The drawback of seq( is that you can't do any I/O or store any variables inside the expression.
Predefined list iteration function
Go to the LIST menu and check out all the operations under OPS and MATH. These predefined function are always going to be faster than a for loops or even a seq( expression designed to do the same thing.