/* Queue (Rosetta code) in Picat. http://rosettacode.org/wiki/Queue/Definition """ Queue/Definition Implement a FIFO queue. Elements are added at one side and popped from the other in the order of insertion. Operations: push (aka enqueue) - add element pop (aka dequeue) - pop first element empty - return truth value when empty Errors: handle the error of trying to pop from an empty queue (behavior depends on the language and platform) See Queue/Usage for the built-in FIFO or queue of your language or standard library. """ This Picat model was created by Hakan Kjellerstrand, hakank@gmail.com See also my Picat page: http://www.hakank.org/picat/ */ % import util. % import cp. main => go. go => println("Test 1"), queue_test1, nl. go2 => println("Test 2"), queue_test2, nl. % % First variant. % empty(Q) => Q = []. push(Queue, Value) = Q2 => Q2 = [Value] ++ Queue. pop(Q,_) = _, Q==[] ; var(Q) => throw $error(empty_queue,pop,'Q'=Q). pop(Queue,Q2) = Queue.last() => Q2 = [Queue[I] : I in 1..Queue.len-1]. % % another variant: always returns the queue which makes % command chaining possible, e.g. % Q := Q.push2(1).push2(2), % Q := Q.pop2(V1).pop2(V2) % empty2() = []. push2(Queue, Value) = Q2 => Q2 = [Value] ++ Queue. pop2(Q,_) = _, Q==[] ; var(Q) => throw $error(empty_queue,pop,'Q'=Q). pop2(Queue,V) = [Queue[I] : I in 1..Queue.len-1] => V = Queue.last(). queue_test1 => % create an empty queue println("Start test 2"), empty(Q0), printf("Create queue %w%n%n", Q0), % add numbers 1 and 2 println("Add numbers 1 and 2 : "), Q1 = Q0.push(1), Q2 = Q1.push(2), % display queue printf("Q2: %w\n\n", Q2), % pop element V = Q2.pop(Q3), % display results printf("Pop : Value: %w Queue: %w\n\n", V, Q3), % test the queue print("Test of the queue: "), ( Q3.empty() -> println("Queue empty"); println("Queue not empty") ), nl, % pop the elements print("Pop the queue : "), V1 = Q3.pop(Q4), printf("Value %w Queue : %w%n%n", V1, Q4), println("Pop empty queue:"), catch(_V = Q4.pop(_Q5),Exception,println(Exception)), nl, println("\nEnd of tests."). queue_test2 => % create an empty queue println("\nstart test2\n"), Q = empty2(), printf("Create queue %w%n%n", Q), % add numbers 1 and 2 println("Add numbers 1 and 2 : "), Q := Q.push2(1).push2(2), % display queue printf("Q: %w\n\n", Q), % pop element Q := Q.pop2(V), % display results printf("Pop : Value: %w Queue: %w\n\n", V, Q), % test the queue print("Test of the queue: "), ( Q.empty() -> println("Queue empty"); println("Queue not empty") ), nl, % pop the elements print("Pop the queue : "), Q := Q.pop2(V2), printf("Value %w Queue : %w%n%n", V2, Q), println("Pop empty queue:"), catch(_ = Q.pop2(_V),Exception,println(Exception)), % command chaining println("\nCommand chaining: "), Q := Q.push2(3).push2(4), Q := Q.pop2(V3).pop2(V4), printf("V3: %w V4: %w\n", V3, V4), nl, println(q=Q), println("\nEnd of tests.").