I'm working on defining a List in Alloy but I'm stuck.
This is what I have so far (it acts like a LinkedList):
module List
// The List signature
lone sig List { rootElement: lone Element }
// A list element signature
sig Element { nextElement: lone Element }
// Prevents an Element from referencing itself
fact preventElementLooping {
no ele: Element | ele = ele.nextElement
}
// Zero Element outliers
fact allElementsBelongToOneList {
all ele: Element | one list: List | ele in list.rootElement.*nextElement
}
// Prevents Elements from referencing a Element before it in the List
fact preventCycle {
no ele: Element | ele in ele.^nextElement
}
This all looks good to me and I feel like this is correct.
I'm trying to define 3 predicates for this list definition:
Create: Should create an empty list
Put: Should add an item to the end of the list
Find: Should return all indices in the list that match a given element
pred create(list, list":List) {
list".rootElement = none
}
pred put(list, list":List, ele: Element) {
list".rootElement = ele
}
pred find [list:List, ele: Element] {
ele = list.rootElement or ele in list.rootElement.^nextElement
}
This is what I need help with I feel like I'm missing something in those 3 preds.
My questions:
Am I over complicating things by trying to use a linked list? How would you just do a normal list?
Put is correct for the first put but fails when you need to put again as it just replaces the root element
Find is the big struggle. I need to store the indices somewhere to return them right? Also I thought alloy only had bare bones understanding of Numbers for indexes (I believe only allowing -7 to 8). Should index be its own signature?
Thanks in advance
There are several ways to define a notion of list in Alloy, yours is a possibility, depending no what you expect to do then.
I don't see why you want to make List a lone sig?
Another remark is that your list doesn't contain any data, only "elements" (I would call them cells), perhaps because it's of no use in your spec? Anyhow, you could make your module generic and store data in cells, e.g.:
module List[Data]
sig List { rootElement: lone Element }
sig Element { data: one Data, nextElement: lone Element }
Your facts can also be improved:
By having only one fact rejecting all forms of cycles.
By only asking for elements to belong to some list rather than exactly one.
Finally, regarding operations, I suggest you take a look at how the standard library models lists and operations:
util/seqrel specifies lists as relations
util/sequence specifies lists as signatures holding elements
util/sequniv is like util/seqrel but relies on builtin integer indices and is implemented in an ad hoc concrete syntax based on the seq keyword.
Related
I'm trying to simply iterate through a list, made up of two list objects I have. I want to do this without having to create a third list variable object that is the concatenation of the two, and without two separate loops going each through a list respectively.
I'm pretty sure I've done this before, but I can't find how to do it anymore.
This is the code that I am trying but it doesn't work properly, as it takes what I've written as a list of lists. That is not my intention. I'm looking for it to iterate through elements of list1, then elements of list2. I'm convinced there is a way to format the {list1, list2} within the statement so that this is the case.
for (auto e : {list1, list2}) { // How can I formulate <<<list1, list2>>>
// so that it takes the concatenation of list elements?
std::cout << e << newLine;
}
Looking to have an output like: list1[0], list1[1], list2[0], list2[1].
A simple way to test effectiveness is whether auto registers as the "list type" or the "element type". I'm looking for the element type.
Something along these lines perhaps:
for (auto& l : {list1, list2}) {
for (auto& e : l) {
std::cout << e;
}
}
In flutter/dart, how can I add elements to a list whilst ensuring that every new entry is unique (i.e. no duplicates).
So we know how to add elements to a list:
List myList = [];
then
myList.add(...);
but I'd like to know how to make sure that whatever has been added has not been added before.
Many thanks,
You should consider using a set. A set is an unordered collection of unique items.
var mySet = <String>{};
mySet.add('something');
Optionally, you may use the Dart´s Extensions function
extension ListExtension<E> on List<E> {
void addAllUnique(Iterable<E> iterable) {
for (var element in iterable) {
if (!contains(element)) {
add(element);
}
}
}
}
Use a Map for the initial adding, Maps will not let duplicates then convert from Map to list.
Maps are Name Value pairs so if these are strings just set the name and value the same, if it is an object set the "uniqueID" as the name and the object as the value...
Then you can take the Name set or usually Value set and turn that into a list for iteration and looping.
https://www.tutorialspoint.com/dart_programming/dart_programming_map.htm
Empty lists are ... strange, to a Prolog beginner like myself. I would say that it isn't possible to write an empty list [] as a difference list T1-T2 just as it isn't possible to write an atom as a difference list. However, I would guess that to use recursion, there must be a way to use [] in a difference list setting. I have Google'd for this but I cannot find an answer, and Bratko (Prolog Programming for AI) only briefly touches the subject.
So, is it possible to write an empty list as a difference list in Prolog, if so how and when would it be useful?
Problems with understanding this topic are typically due to using misleading terminology.
As recommended in tutorial.pdf and especially pap95.pdf, use for example list difference or simply difference.
Section 5 of Teaching beginners Prolog contains relevant reasons for this.
The empty list is uniquely denoted by the atom [].
Note that a list difference always means reasoning about two lists, and due to this categorical difference between a single and multiple lists, you can at best find some correspondence or analogy, but not identity between the empty list and a list difference.
I completely support the view expressed in the paper above that you should focus on using DCGs, at least at first. Reasoning about differences explicitly will come naturally later to you.
Appending two list differences means just a unification of first diff's end pointer with the second one's head. With regular lists it requires retracing of the whole list structure of the first list. Thus repeated concatenation on the right is linear with the list difference technique, and quadratic with plain lists.
When all the intended concatenations are done, to return the whole structure as a plain list to a caller we just unify the "end pointer" logvar with [].
In C terms, list difference is a portion of singly-linked list where we maintain two variables: its head pointer but also its tail pointer:
// typedef struct { int payload; node* next } node;
typedef struct { node** head; node** tail } list_diff;
Now each concatenation is just an assignment of the end pointer:
void diff_concat( list_diff* a, list_diff* b)
{
*(a -> tail) -> next = *(b -> head);
a -> tail = b -> tail;
}
And finalization is
void diff_finalize( list_diff* a)
{
*(a -> tail) = NULL; // or some sentinel value, whatever
}
In Prolog we could represent it as a binary term like -/2, e.g. -(A,B) or A-B.
But (as in C also) there's no actual need to build an actual structure in memory just for holding the two pointers; we can just maintain two logvars individually. Or let DCGs do it for us.
The above was the motivational introduction to list difference technique, "what are they good for?". It also makes clear that the representation of empty difference is
list_diff* d;
*(d -> head) = *(d -> tail);
Or in Prolog, a pair of logvars unified with each other: L-L, var(L). To see why, see what happens when empty diff is appended with some other diff on its right (it is always on the right that we append things, thus growing the lists in the top-down manner). My C may be off here, the idea being that by setting the tail the appending to an empty diff will also update its head.
I am looking for a functional way to solve a list iteration/sorting problem I am having in C++.
Consider a list of elements of the following type:
struct SomeElement
{
/* ... functions and and additional data omitted ... */
int weight;
}
A std::list<SomeElement> or event std::vector<SomeElement> exists. I would like to query that list to return the element that:
Satisfies a given condition, i.e., MyPredicate(someElement) == true, and
has the smallest value for its weight attribute of all objects satisfying the condition.
My list has any number of elements, and zero to all might satisfy the given condition.
I know how to do that in general, e.g., I could sort the list and then pick the first object that satisfies the condition using std::find_if, or simply loop over it with a for loop, etc. However, I'd like to solve the problem in a functional way.
Is there a way I can use list predicates, generator expressions, and list comprehensions in C++? I'd like to write something along the lines of:
myList
.where((SomeElement const& e) { MyPredicate(e); })
.min([](SomeElement const& a, SomeElement const& b) { a.weight < b.weight; });
Is it possible with C++'s STL, or a Boost library?
Why do the list/ring types in golang use the extra structs Element/Ring for the individual items and not interface{} ? I am assuming there is some benefit but I cannot see it.
Edit: I meant to ask about the api and NOT about the use of Element/Ring in the implementation. The implementation could still use a non exported type but have the api give and take an interface{}, so why make the users go in and out of Element/Ring?
Edit2: As an example the list Back() function could be like
func (l *List) Back() interface{} {
if l.len == 0 {
return nil
}
return l.root.prev.Value
}
Where the list still uses Element internally but it would be just element (unexported) since it wouldn't return it but only return the value.
container/list is linked list, so it'll be beneficial to have List struct that can operate on the list as a whole and keep track of the beginning and end of a list.
Since it's a linked list, you want to be able to link items together and navigate from one item to the next or the previous item. That requires a struct that hold pointers to the next and the previous item as well as allowing you to navigate to those items (with the Next() and Prev() functions). The Element struct serves that purpose, it contains pointers to the next/previous item, and the actual value.
Here's how the struct's are defined, and they have various member functions as well
type List struct {
root Element // sentinel list element, only &root, root.prev, and root.next are used
len int // current list length excluding (this) sentinel element
}
type Element struct {
// Next and previous pointers in the doubly-linked list of elements.
// To simplify the implementation, internally a list l is implemented
// as a ring, such that &l.root is both the next element of the last
// list element (l.Back()) and the previous element of the first list
// element (l.Front()).
next, prev *Element
// The list to which this element belongs.
list *List
// The value stored with this element.
Value interface{}
}
container/ring does not have an "extra" struct as you imply. There's only the Ring struct which links one item to the next/previous item and also holds the value. There's no start/end of a Ring, so there's no need to have a struct that operates on a ring as a whole or keeps track of the start.
type Ring struct {
next, prev *Ring
Value interface{} // for use by client; untouched by this library
}
They contain filtered or unexported fields.
Package list
File list.go:
// Package list implements a doubly linked list.
// Element is an element of a linked list.
type Element struct {
// Next and previous pointers in the doubly-linked list of elements.
// To simplify the implementation, internally a list l is implemented
// as a ring, such that &l.root is both the next element of the last
// list element (l.Back()) and the previous element of the first list
// element (l.Front()).
next, prev *Element
// The list to which this element belongs.
list *List
// The value stored with this element.
Value interface{}
}
Package ring
File ring.go:
// Package ring implements operations on circular lists.
// A Ring is an element of a circular list, or ring.
// Rings do not have a beginning or end; a pointer to any ring element
// serves as reference to the entire ring. Empty rings are represented
// as nil Ring pointers. The zero value for a Ring is a one-element
// ring with a nil Value.
//
type Ring struct {
next, prev *Ring
Value interface{} // for use by client; untouched by this library
}
Obviously, the type of Element and Ring can't be interface{} because it would make no sense. You can't have a method on an interface type.
The Go Programming Language Specification
Method declarations
A method is a function with a receiver. A method declaration binds an
identifier, the method name, to a method, and associates the method
with the receiver's base type.
MethodDecl = "func" Receiver MethodName ( Function | Signature ) .
Receiver = "(" [ identifier ] [ "*" ] BaseTypeName ")" .
BaseTypeName = identifier .
The receiver type must be of the form T or *T where T is a type name.
The type denoted by T is called the receiver base type; it must not be
a pointer or interface type and it must be declared in the same
package as the method. The method is said to be bound to the base type
and the method name is visible only within selectors for that type.