Short answer: To express "there is no other child of Parent", i.e., "there is no child of Parent different from Child", you would write:
single_child(Child) :-
child_of(Child, Parent),
\+ ( child_of(Sibling, Parent), Sibling \= Child ).
(Not tested because you didn't give us any test cases.)
A key point is that the two goals child_of(Sibling, Parent), Sibling \= Child together express the condition "there is another child of Parent", so you have to negate them together to get the right meaning. My preferred way would be to extract this to a separate predicate meaning "Person has sibling Sibling":
person_sibling(Person, Sibling) :-
child_of(Person, Parent),
child_of(Sibling, Parent),
Person \= Sibling.
And then write single_child as:
single_child(Child) :-
child_of(Child, _Parent), % Child is somebody's child
\+ person_sibling(Child, _Sibling). % Child has no siblings
Another key point is that you should only use \= when both sides are bound to non-variable terms. In your code Sibling is not bound to anything at the point you reach the \= goal. That is why my code first calls child_of(Sibling, Parent) to give Sibling a concrete value before then comparing that concrete value to Child. Modern Prologs usually have a dif predicate that does not have this restriction: You can write dif(Child, Sibling), child_of(Sibling, Parent) and it will do the right thing even if some operands are unbound variables at that point. If your Prolog has dif, you should use it instead of \=. You can and usually should use dif before all of its operands become bound.
Final note: You shouldn't just blindly make all your predicates discontiguous. It may be useful for facts like child_of or female if you want to mix up the order of those facts. But as a beginner you should never encounter a situation where it makes sense for a rule like single_child to be marked discontiguous. In fact, the annotation does not make any sense for a predicate that consists of a single clause.