Is there a standard method for removing duplicate entries in an array, but preserving the order?
e.g.
#(c a b a a b) withoutDuplicates "-> #(c a b)"
I used to use removeDuplicates, but apparently that's an extension method added by Roassal (so I cannot always use it)
Written by hand, the best solution (I have) is
a := #(c a b a a b).
d := OrderedDictionary new.
a do: [ :each | d at: each put: true ].
d keys. "-> #(c a b)"
But is there a standard way?
Same as yours but shorter in terms of text to type, not performance.
(#(c a f b c a d c a e f f) collect: [ :e | e -> true ]) asOrderedDictionary keys
Your solution looks very good to me. Here is another one:
withoutDuplicates
| visited |
visited := Set new.
^self select: [:element |
(visited includes: element) not
ifTrue: [visited add: element];
yourself]
This one is more verbose but uses (only) one additional collection: the visited set. An OrderedDictionary, on the other hand, has two internal collections a Dictionary and the sequence of orderedKeys. If you are not concerned with space I would suggest using your solution.
As an aside note I would say that the use of #yourself here is a bit unusual. It follows the pattern:
^boolean ifTrue: [self doThis]; yourself
Which has a side effect (self doThis) when boolean is true and answers with boolean in either case. Most people would write it as:
boolean ifTrue: [self doThis].
^boolean
but this requires the addition of a block temporary because in our case boolean refers to the expression (visited includes: element) not which we shouldn't repeat.
OR...
... you could take this opportunity to implement OrderedSet in Pharo...
Related
I am currently attempting to use VST to verify the correctness of a project which involves a global array of doubles. However, when attempting to access the array I have that the head of the array is given as a data_at statement while the rest of the array is given as a sepcon list of mapsto statements and there does not appear to be any way to prove field_compatible for elements beyond the head of the array.
Trying to access elements beyond offset_val 0 seems to inevitably involve proving a size_compatible statement. This is where I run into a problem. Since the alignment of tdouble is set to 4 and the size is set to 8, there seems to be a possibility that the head of the array is at Ptrofs.modulus - 12 making size_compatible false for the next element in the array. Am I going about this the wrong way?
I made a toy example with the same problem that I've mentioned above.
double dbls[] = {0.0, 1.1};
int main() {
double sum;
sum = dbls[0] + dbls[1];
return 0;
}
I will frame my answer in the form of a Coq development:
Require Import VST.floyd.proofauto.
Require Import VST.progs.foo.
#[export] Instance CompSpecs : compspecs. make_compspecs prog. Defined.
Definition Vprog : varspecs. mk_varspecs prog. Defined.
Definition main_spec :=
DECLARE _main
WITH gv : globals
PRE [] main_pre prog tt gv
POST [ tint ] main_post prog gv.
Definition Gprog : funspecs := [ ].
Lemma body_main: semax_body Vprog Gprog f_main main_spec.
Proof.
start_function.
(* Remark 1: it seems to be a bug in VST 2.11.1 (and earlier versions)
that the array is not packaged up into
(data_at Ews (tarray Tdouble 2) ...)
the way it ought to be. This seems to work better for integer
arrays, et cetera.*)
(* Remark 2: you are right to be concerned about alignment, but
VST addresses that issue correctly. Any extern global variable
in a C program, such as your [dbls] array, is aligned at the
biggest possible alignment requirement. VST expresses this
with the "headptr" predicate, and for any identifier id,
(gv id) is a headptr. So therefore, *)
assert_PROP (headptr (gv _dbls)) by entailer!.
(* and you can see above the line, H: headptr (gv _dbls). *)
Print headptr.
(* This shows that (gv _dbls) must be at offset zero within
some block, which guarantees alignment at any type.
One useful consequence is proved by the lemma
headptr_field_compatible: *)
Check headptr_field_compatible.
(* And now, let's apply that lemma: *)
pose proof headptr_field_compatible (tarray tdouble 2) nil _
H (eq_refl _) Logic.I ltac:(simpl; rep_lia).
(* So we see that as long as the pesky 'align_compatible_rec' is proved,
the pointer (gv _dbls) should be 'field_compatible' with the array
type that you want. And it's straightforward though tedious to prove
the 'align_compatible_rec' premise, as follows: *)
spec H0.
apply align_compatible_rec_Tarray; intros.
Search align_compatible_rec.
eapply align_compatible_rec_by_value; [ reflexivity | ].
apply Z.divide_add_r.
apply Z.divide_0_r.
apply Z.divide_mul_l.
apply Z.mod_divide; compute; intros; congruence.
(* Normally, VST users shouldn't have to do this 'by hand'.
We should fix the bug (failure to nicely package the precondition).
But in the interim, perhaps this gives what you need for a workaround.*)
What does this do, and is there a simpler way to write it?
Collection>>into: a2block
| all pair |
all := ([:allIn :each| allIn key key: allIn value. each])
-> (pair := nil -> a2block).
pair key: all.
self inject: all
into: [:allIn :each| allIn value: (allIn key value: allIn value value: each). allIn].
^all value
If you want to find out, the best way is to try it, possibly step by step thru debugger.
For example, try:
(1 to: 4) into: #+.
(1 to: 4) into: #*.
You'll see a form of reduction.
So it's like inject:into: but without injecting anything.
The a2block will consume first two elements, then result of this and 3rd element, etc...
So we must understand the selector name as inject:into: without inject:: like the implementation, it's already a crooked way to name things.
This is implemented in Squeak as reduce:, except that reduce: would be well too obvious as a selector, and except that it would raise an Error if sent to an empty collection, contrarily to this which will answer the strange recursive artifact.
The all artifact contains a block to be executed for reduction as key, and current value of reduction as value. At first step, it arranges to replace the block to be executed with a2block, and the first value by first element. But the recursive structure used to achieve the replacement is... un-necessarily complex.
A bit less obfuscated way to write the same thing would be:
into: a2block
| block |
self ifEmpty: [self error: 'receiver of into: shall not be empty'].
block := [:newBlock :each| block := newBlock. each].
^self inject: a2block into: [:accum :each| block value: accum value: each]
That's more or less the same principle: at first iteration, the block is replaced by the reduction block (a2block), and first element is accumulated.
The reduction only begins at 2nd iteration.
The alternative is to check for first iteration inside the loop... One way to do it:
into: a2block
| first |
self ifEmpty: [self error: 'receiver of into: shall not be empty'].
first := Object new.
^self inject: first into: [:accum :each |
accum == first
ifTrue: [each]
ifFalse: [a2block value: accum value: each]].
There are many other ways to write it, more explicitely using a boolean to test for first iteration...
I have an object like a Dictionary('CMFireAutomataModel'->a Dictionary('nbAshes'->193 'nbFires'->851 ) ) and I would like to have something like Dictionary('nbAshes'->193 'nbFires'->851 ).
I don't know how to "unstack" the first dictionary.
Let's say you have a Dictionary whose keys are Strings and its values are Numbers or Dictionaries of the same sort (i.e., with keys that are strings and values that are dicts or numbers). What we want is a way to "promote" or "unstack" all string keys and numbers to the mother dictionary.
unstack: aDictionary
| dict |
dict := aDictionary class new.
aDictionary keysAndValuesDo: [:k :v | | d |
v isNumber
ifTrue: [dict at: k put: v]
ifFalse: [
d := self unstack: v.
dict addAll: d associations]].
^dict
Note that I've used aDictionary class new to make sure the method answers with a Dictionary of the same kind (e.g., an IdentityDictionary, etc.).
Note also that the method could go in any class. I haven't put it in Dictionary because I don't think this is general enough (even though that would have simplified the code a little bit)
New to Ocaml and have been working on a problem I haven't seen answered yet.
I'm working on a function where there is a tuple of 2 lists that are checked for equivalence.
Example:
# equivalence ([1;2],[1;2]);;
- : bool = true
# equivalence ([1;2],[2;1]);;
- : bool = true
# equivalence ([1;2],[1]);;
- : bool = false
Code I have:
let rec equivalent(a,b) = match a, b with
| [], [] -> true
| [], _
| _, [] -> false
| c::cc, d::dd -> if c = d then equivalent(cc,dd) else false;;
I know the problem lies with the last line. I can get a result of true if all elements are in the same order, but out of order it is a result of false. I'm having trouble going through one list to see if the other list has the element. I've tried to use List.nth, .hd, and .tl (not allowed to use .map or .itr) and have also tried to avoid the imperative features of Ocaml. Any suggestions or somewhere I should look? Thanks.
I assume this is some homework where you have to treat lists as poor mans set.
As Bergi mentioned performance wise the best would be to first sort both list and then compare them with your existing code. But that is probably not how you are supposed to solve this.
Assuming the lists are mend to be sets with not duplicate entries then equivalence of a and b means that a contains every element of b and b contains every element of a.
Start by writing a function contains: 'a -> 'a list -> bool that checks if an item is in a list. Next a function contains_all: 'a list -> 'a list -> bool that uses contains to check if every item in the first list is in the second. That then gives you
let equivalence a b = (contains_all a b) && (contains_all b a)
If your lists can contains duplicates then go with sorting the lists first. Anything else is just too impractical.
Note: contains exists as List.mem if you are allowed to use that.
I'm interested in generalizing some computational tools to use a Cayley Table, meaning a lookup table based multiplication operation.
I could create a minimal implementation as follows :
date CayleyTable = CayleyTable {
ct_name :: ByteString,
ct_products :: V.Vector (V.Vector Int)
} deriving (Read, Show)
instance Eq (CayleyTable) where
(==) a b = ct_name a == ct_name b
data CTElement = CTElement {
ct_cayleytable :: CayleyTable,
ct_index :: !Int
}
instance Eq (CTElement) where
(==) a b = assert (ct_cayleytable a == ct_cayleytable b) $
ct_index a == ct_index b
instance Show (CTElement) where
show = ("CTElement" ++) . show . ctp_index
a **** b = assert (ct_cayleytable a == ct_cayleytable b) $
((ct_cayleytable a) ! a) ! b
There are however numerous problems with this approach, starting with the run time type checking via ByteString comparisons, but including the fact that read cannot be made to work correctly. Any idea how I should do this correctly?
I could imagine creating a family of newtypes CTElement1, CTElement2, etc. for Int with a CTElement typeclass that provides the multiplication and verifies their type consistency, except when doing IO.
Ideally, there might be some trick for passing around only one copy of this ct_cayleytable pointer too, perhaps using an implicit parameter like ?cayleytable, but this doesn't play nicely with multiple incompatible Cayley tables and gets generally obnoxious.
Also, I've gathered that an index into a vector can be viewed as a comonad. Is there any nice comonad instance for vector or whatever that might help smooth out this sort of type checking, even if ultimately doing it at runtime?
You thing you need to realize is that Haskell's type checker only checks types. So your CaleyTable needs to be a class.
class CaleyGroup g where
caleyTable :: g -> CaleyTable
... -- Any operations you cannot implement soley by knowing the caley table
data CayleyTable = CayleyTable {
...
} deriving (Read, Show)
If the caleyTable isn't known at compile time you have to use rank-2 types. Since the complier needs to enforce the invariant that the CaleyTable exists, when your code uses it.
manipWithCaleyTable :: Integral i => CaleyTable -> i -> (forall g. CaleyGroup g => g -> g) -> a
can be implemented for example. It allows you to perform group operations on the CaleyTable. It works by combining i and CaleyTable to make a new type it passes to its third argument.