edge constructor accepts source and target