Home > Community > Blogs > Custom IC Design > skill for the skilled sorting with skill
 
Login with a Cadence account.
Not a member yet?
Create a permanent login account to make interactions with Cadence more conveniennt.

Register | Membership benefits
Get email delivery of the Custom IC Design blog (individual posts).
 

Email

* Required Fields

Recipients email * (separate multiple addresses with commas)

Your name *

Your email *

Message *

Contact Us

* Required Fields
First Name *

Last Name *

Email *

Company / Institution *

Comments: *

SKILL for the Skilled: Sorting With SKILL++

Comments(0)Filed under: Virtuoso, SKILL, Team SKILL, programming, SKILL++, sorting, functions, sort

In the previous couple of SKILL for the Skilled postings we looked at some of the features of SKILL++. In fact, we saw local functions, higher-order functions, and lexical scoping. In this episode of SKILL for the Skilled I would like to show a few more practical examples of these concepts.

Functions are first class

In the SKILL language, functions are themselves first class objects. They can be created dynamically, and they can be passed around as arguments to other functions. We'll see in the examples how to write functions that generate functions, and why you might want to do that.

Review of the SKILL sort function

The SKILL primitive sort function, takes two arguments. The first is the list to be sorted, and the second is a function designator indicating a compare predicate. A predicate is a function whose return value is to be interpreted as TRUE or FALSE. A compliant compare predicate (for sort) promises to accept two arguments and return a boolean value indicating whether the two arguments given are in order in some appropriate sense. Often there is already a built-in SKILL function which does the type of comparison needed, and sometimes an on-the-fly function does the trick. The code in example 5.1 uses a pre-existing function, alphalessp as a compare predicate. In this case, the sort function reorders the list of strings alphabetically.

Sorting with built-in sort predicates

 

;; Example 5.1
(sort (list "this" "is" "a" "list" "of" "words")
'alphalessp)
==> ("a" "is" "list" "of" "this" "words")

As seen previously, if your code is in SKILL++, you can simply reference the global variable whose name is the same as the function name: alphalessp.

 

;; Example 5.2
(inScheme
(sort (list "this" "is" "a" "list" "of" "words")
alphalessp))
==> ("a" "is" "list" "of" "this" "words")

For the rest of this article, please assume all top level SKILL expressions reside in a (inScheme ...) form.

Implementing SKILL++ sort predicates

The compare predicate of sort may actually be any callable object. Several types of objects are callable in SKILL. Symbols such as alphalessp are callable if they name existing functions or are somehow auto-loadable. Function objects created by lambda are also callable.

Global functions get created and named when you use procedure or defun. As we saw previously functions can also be created and named locally using flet and labels. But you can also create nameless functions with lambda.

The code in example 5.3 creates a function named fileLengthLessp.

;; Example 5.3
(defun fileLengthLessp (f1 f2)
(lessp (fileLength f1)
(fileLength f2)))

The code in example 5.4 creates an equivalent function, i.e., a function that does the same thing as fileLengthLessp when called, but which has no name. You have to store the value in a variable or pass the value directly to a function, such as to the sort function.

 

;; Example 5.4
(lambda (f1 f2)
(lessp (fileLength f1)
(fileLength f2)))

In the following examples (5.5, 5.6, and 5.7) we want to sort a list of file names (strings) according to the file size (in bytes). There are several ways to do this. There is a SKILL built-in function to return the file size, but there is no built-in SKILL function which compares file sizes. However Example 5.3 above implements one named fileLengthLessp. We can use that function as an argument to sort.

 

;; Example 5.5
(sort (getDirFiles ".")
fileLengthLessp)
You can also build the function on-the-fly without a name as in Example 5.6.

 

;; Example 5.6
(sort (getDirFiles ".")
(lambda (f1 f2)
(lessp (fileLength f1)
(fileLength f2))))

You can also do this using flet as in example 5.7.

 

;; Example 5.7
(flet ((lesspFileLength (f1 f2)
(lessp (fileLength f1)
(fileLength f2))))
(sort (getDirFiles ".")
lesspFileLength))

 

Reversing the sort order

Two more examples are seen in examples 5.8 and 5.9. Example 5.8 shows how to sort a list of strings in decreasing order according to (string) length; i.e., longest string first.

 

;; Example 5.8
(sort list_of_strings
(lambda (a b)
(greaterp (strlen a)
(strlen b))))
Example 5.9 shows how to sort a list of sub-lists by decreasing order according to (list) length.
;; Example 5.9
(sort list_of_lists
(lambda (a b)
(greaterp (length a)
(length b))))

 

Components of the sort predicate

Notice the similar code structure in examples 5.6, 5.8, and 5.9. There are a couple characteristics of the compare function which we can factor out.

  • test: the kind of relation function, numerical relation such as greater (greaterp) than or less than (lessp), or an alphabetic type of relation such as alphalessp.
  • key: the kind of attribute we want to compare such as length, strlen, fileLength, or identity.
The identity function

It will simplify a few things later if we first define a very simple function called identity to be a unary function which returns its argument. The identity function defined in example 5.10 is to function application, as zero is to addition, and 1 is to numerical multiplication.

;; Example 5.10

(defun identity (x)
x)
Higher order functions -- calculating a sort predicate

We can use SKILL++ to calculate the compare function to pass to sort. Writing functions that generate functions is an easy thing to do in SKILL++.

 

;; Example 5.11
(defun genCmpFunction (@key (test lessp)
(key identity)) ;; see example 5.10
(lambda (A B)
(test (key A)
(key B))))

The function, genCmpFunction defined in Example 5.11, can be called with keyword arguments ?test and ?key and returns a function which is compatible with sort; i.e., it returns a binary function which can be used as a sort predicate. The names test, and key are somewhat standard names--even if a bit confusing. Usage examples are shown in example 5.12. The key defaults to the identity function, and the test defaults to the lessp function.

Using the higher order function

Now, the SKILL sort can be used in a more generalized way. We can rewrite the code examples in 5.5, 5.6, and 5.7.

 

;; Example 5.12

;; reimplementation of example 5.6
;; sort a list of file names by increasing file size
(sort (getDirFiles ".")
(genCmpFunction ?key fileLength))

;; reimplementation of example 5.8
;; sort a list of strings by decreasing string length
(sort list_of_strings
(genCmpFunction ?key strlen
?test greaterp))

;; reimplementation of example 5.9
;; sort a list of sub-lists by decreasing list length
(sort list_of_lists
(genCmpFunction ?key length
?test greaterp))
Reimplementing the sortcar function

Notice that if the built-in function sortcar did not exist in SKILL, we could implement it using sort as shown in example 5.13.

 

;; Example 5.13
(defun sortcar (list predicate)
(sort list
(genCmpFunction ?test predicate
?key car)))

Sorting objects from the Cadence Database

The genCmpFunction can generate useful sort predicates for sorting data base objects under various criteria. Example 5.14 shows how to sort shapes in a Virtuoso layout from top-to-bottom according to top edge.

 

;; Example 5.14
(sort (geGetEditCellView)->shapes
(genCmpFunction ?test greaterp
?key topEdge))
Example 5.15 shows how to sort the db-instances in a schematic alphabetically according to instance name. In this example, we pass ?key as a function which will retrieve value of the name property from a db-instance.

 

;; Example 5.15
(sort (geGetEditCellView)->instances
(genCmpFunction ?test alphalessp
?key (lambda (i) i->name)))

Review

In this posting we looked at the following concepts.

  • The SKILL built-in sort function
  • Sorting list of string alphabetically (examples 5.1, 5.2)
  • Sorting file name by file size (examples 5.5, 5.6, 5.7)
  • Calculating sort predicates programmatically (example 5.11)
  • Reimplementing sortcar based on a generalized sort predicate
  • Using higher-order function in conjunction with sorting strings and db-objects.
To Be Continued

In the next posting we'll see more examples of how to use these types of higher order functions with virtuoso, for example to sort pin figures clockwise around the boundary of the cellView. In addition we'll generalize the genCmpFunction further to allow for secondary and ternary sorting criteria.

Jim Newton

Previous Posts

SKILL for the Skilled: Continued Introduction to SKILL++

SKILL for the Skilled: What is SKILL++?

SKILL for the Skilled: Rule of English Translation

SKILL for the Skilled:  Making Programs Clear and Concise

 

Comments(0)

Leave a Comment


Name
E-mail (will not be published)
Comment
 I have read and agree to the Terms of use and Community Guidelines.
Community Guidelines
The Cadence Design Communities support Cadence users and technologists interacting to exchange ideas, news, technical information, and best practices to solve problems and get the most from Cadence technology. The community is open to everyone, and to provide the most value, we require participants to follow our Community Guidelines that facilitate a quality exchange of ideas and information. By accessing, contributing, using or downloading any materials from the site, you agree to be bound by the full Community Guidelines.