Here is some (truly appalling, almost prose it has been noted) pseudocode, in which one wants to find possible replacements for a particular Functional Group (for example, a nitro, a vinyl halide, a sulphonamide, etc.)
1. Search StARlite for the all examples of the Functional Group 2. Identify all fragments that these Functional Groups are attached to (call these 'Contexts') 3. Search StARlite for all Contexts, then identify the corresponding Replacement Functional Groups 4. Build a table of Replacement Functional Groups and the count the frequency of each type of interchange (this frequency list is pretty useful in its own right) 5. Retrieve quantitative values of binding energy difference (using endpoints such as IC50, Ki, Kd, etc., constraining the comparison to the same assay_ids from the same doc_ids 6. Use these binding energy differences to compute an expectation value for the binding energy difference between the Functional Group and the Replacement Functional Group
So a good bioisostere would preserve (or improve) binding energy, these are then pretty easy to identify from the tables generated above. Of course, with the multiple end points stored in StARlite, and the generality of the approach, the same basic workflow can be used to identify functional group replacements that can improve half-life, solubility, logD, etc., etc.
Here is an old slide of a real case, the replacement of a carboxylic acid with other functional groups. Hopefully, with the background above, the figure is self explanatory....
The picture used in the header of the post is from the excellent and very amusing B'eau Bo D'Or blog, and I think perfectly illustrates bioisosterism - albeit in a context that is completely opaque to anyone not steeped in the 70's and 80's popular culture of the United Kingdom.